diff --git a/.gitignore b/.gitignore index a40987321..04de5d664 100644 --- a/.gitignore +++ b/.gitignore @@ -83,7 +83,7 @@ celerybeat-schedule # Environments .env -.venv +.venv* env/ venv/ ENV/ diff --git a/other/materials_designer/create_adatom_defect.ipynb b/other/materials_designer/create_adatom_defect.ipynb index 296c94f98..ac3c87a11 100644 --- a/other/materials_designer/create_adatom_defect.ipynb +++ b/other/materials_designer/create_adatom_defect.ipynb @@ -47,28 +47,32 @@ "id": "5e43ff288847b784" }, { + "metadata": {}, "cell_type": "code", "source": [ + "from mat3ra.made.tools.build.defect.enums import AdatomPlacementMethodEnum\n", + "from mat3ra.made.tools.build.slab.termination_utils import select_slab_termination\n", + "\n", + "ELEMENT = \"Si\" # Chemical element of the adatom\n", "DEFECT_CONFIGS = [\n", " {\n", - " \"defect_type\": \"adatom\",\n", - " \"placement_method\": \"equidistant\",\n", - " \"chemical_element\": \"Si\",\n", - " \"position_on_surface\": [0.5, 0.5],\n", - " \"distance_z\": 2.0,\n", - " \"use_cartesian_coordinates\": False\n", - " },\n", + " \"type\": \"adatom\",\n", + " \"coordinate\": [0.5, 0.5], # Crystal coordinates on the surface (x, y)\n", + " \"distance_z\": 1.0, # Method to place the adatom\n", + " \"element\": ELEMENT,\n", + " }\n", "]\n", + "PLACEMENT_METHOD = AdatomPlacementMethodEnum.NEW_CRYSTAL_SITE # Method to place the adatom, e.g., \"NEW_CRYSTAL_SITE\", \"EQUIDISTANT\", \"EXACT_COORDINATE\"\n", + "\n", + "\n", "# Slab parameters\n", "MILLER_INDICES = (1, 1, 1) # Miller indices of the surface\n", "SLAB_THICKNESS = 3 # Thickness of the slab in unit cells\n", - "VACUUM = 6 # Vacuum thickness in Angstrom\n", - "SUPERCELL_MATRIX = [[2, 0, 0], [0, 2, 0], [0, 0, 1]] # Supercell matrix for the slab" + "VACUUM = 5.0 # Vacuum thickness in Angstrom\n", + "XY_SUPERCELL_MATRIX = [[2, 0], [0, 2]] # Supercell matrix for the slab\n", + "TERMINATION_FORMULA = None # Stoichiometric formula of the slab termination to be used." ], - "metadata": { - "collapsed": false - }, - "id": "9d8b1890b34d850a", + "id": "b28e2fb6a4ea857f", "outputs": [], "execution_count": null }, @@ -142,7 +146,7 @@ "cell_type": "code", "source": [ "from mat3ra.made.tools.analyze.lattice_planes import CrystalLatticePlanesMaterialAnalyzer\n", - "from mat3ra.made.tools.build.slab.helpers import create_slab\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab, get_slab_terminations\n", "from utils.visualize import visualize_materials as visualize\n", "\n", "material = materials[0]\n", @@ -150,16 +154,16 @@ "analyzer = CrystalLatticePlanesMaterialAnalyzer(material=material, miller_indices=MILLER_INDICES)\n", "slab_terminations = analyzer.terminations\n", "# Get termination from analyzer\n", - "terminations = analyzer.terminations\n", - "termination = terminations[0] # Use first termination\n", + "terminations = get_slab_terminations(material, MILLER_INDICES)\n", + "termination = select_slab_termination(terminations, TERMINATION_FORMULA)\n", "\n", "slab = create_slab(\n", " crystal=material,\n", " termination=termination,\n", " miller_indices=MILLER_INDICES,\n", - " number_of_layers=1,\n", - " vacuum=0,\n", - " xy_supercell_matrix=[[1, 0], [0, 1]],\n", + " number_of_layers=SLAB_THICKNESS,\n", + " vacuum=VACUUM,\n", + " xy_supercell_matrix=XY_SUPERCELL_MATRIX,\n", " use_orthogonal_c=True,\n", " use_conventional_cell=True\n", ")\n", @@ -172,50 +176,19 @@ { "metadata": {}, "cell_type": "markdown", - "source": [ - "## 2. Create the Defect\n", - "### 2.1. Set adatom parameters" - ], + "source": "## 2. Create the Defect", "id": "b386c06587b2f843" }, - { - "metadata": {}, - "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.defect import AdatomSlabPointDefectConfiguration\n", - "\n", - "defect_configurations = [\n", - " AdatomSlabPointDefectConfiguration(\n", - " crystal=slab,\n", - " defect_type=defect[\"defect_type\"],\n", - " placement_method=defect[\"placement_method\"],\n", - " chemical_element=defect[\"chemical_element\"],\n", - " position_on_surface=defect[\"position_on_surface\"],\n", - " distance_z=defect[\"distance_z\"],\n", - " use_cartesian_coordinates=defect[\"use_cartesian_coordinates\"]\n", - " ) for defect in DEFECT_CONFIGS\n", - "]" - ], - "id": "3727ba76ad5101c0", - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Create the adatom" - ], - "metadata": { - "collapsed": false - }, - "id": "489b51f0ee122c48" - }, { "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.defect import create_defects\n", + "from mat3ra.made.tools.build.defect.adatom.helpers import create_multiple_adatom_defects\n", "\n", - "slab_with_adatom = create_defects(defect_configurations)" + "slab_with_adatom = create_multiple_adatom_defects(\n", + " slab=slab,\n", + " defect_dicts=DEFECT_CONFIGS,\n", + " placement_method=PLACEMENT_METHOD.value,\n", + ")" ], "metadata": { "collapsed": false @@ -226,9 +199,7 @@ }, { "cell_type": "markdown", - "source": [ - "## 3. Visualize the Slabs with Adatom" - ], + "source": "## 3. Visualize the Slab with Adatom", "metadata": { "collapsed": false }, @@ -240,10 +211,12 @@ "source": [ "from utils.visualize import visualize_materials as visualize\n", "\n", - "visualize([{\"material\": slab, \"title\": \"Original material\"},\n", - " {\"material\": slab_with_adatom, \"title\": f\"Material with adatom defects\"}],\n", - " viewer=\"wave\"\n", - " )" + "visualize([\n", + " {\"material\": slab, \"title\": \"Original material\"},\n", + " {\"material\": slab_with_adatom, \"title\": f\"Material with adatom defects\"}\n", + "],\n", + " viewer=\"wave\"\n", + ")" ], "id": "256b07fb2dd39ae2", "outputs": [], diff --git a/other/materials_designer/create_cluster_custom_shape.ipynb b/other/materials_designer/create_cluster_custom_shape.ipynb index 0b5813a08..cd5f6414f 100644 --- a/other/materials_designer/create_cluster_custom_shape.ipynb +++ b/other/materials_designer/create_cluster_custom_shape.ipynb @@ -82,8 +82,8 @@ "source": [ "RADIUS = 0.3 # in crystal units\n", "VACUUM = 10.0 # in Angstroms on each side\n", - "SUPERCELL_SIZE = 10 # in crystal units\n", "Z_ORIENTATION = (0, 0, 1) # Miller indices of the slab orientation along the z-axis for the cluster\n", + "USE_CARTESIAN_COORDINATES = False\n", "NAME = \"Icosahedron\" # Name of the cluster" ], "metadata": { @@ -115,7 +115,7 @@ "class CustomCoordinateCondition(CoordinateCondition):\n", " \"\"\"Creates a regular polyhedron shape using SciPy's ConvexHull\"\"\"\n", " radius: float = 1\n", - " center: List[float] = [0.5, 0.5, 0.5]\n", + " center_coordinate: List[float] = [0.5, 0.5, 0.5]\n", "\n", " @property\n", " def _hull_planes(self):\n", @@ -129,12 +129,12 @@ "\n", " def condition(self, coordinate: List[float]) -> bool:\n", " \"\"\"Returns True if point is inside the polyhedron\"\"\"\n", - " point = np.array(coordinate) - self.center\n", + " point = np.array(coordinate) - self.center_coordinate\n", " return all(np.dot(plane[:3], point) + plane[3] <= 0\n", " for plane in self._hull_planes)\n", "\n", " \n", - "condition = CustomCoordinateCondition(radius=RADIUS).condition" + "condition = CustomCoordinateCondition(radius=RADIUS)" ], "metadata": { "collapsed": false @@ -181,13 +181,9 @@ { "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.nanoparticle import SlabBasedNanoparticleConfiguration\n", - "\n", - "config = SlabBasedNanoparticleConfiguration(\n", - " material=materials[0],\n", - " condition_builder=condition,\n", - " supercell_size=SUPERCELL_SIZE,\n", - ")" + "from mat3ra.made.tools.build.nanoparticle.helpers import create_nanoparticle_from_material\n", + "material = materials[0]\n", + "cluster = create_nanoparticle_from_material(material=material,condition=condition, orientation_z=Z_ORIENTATION, vacuum_padding=VACUUM, use_cartesian_coordinates=USE_CARTESIAN_COORDINATES)" ], "metadata": { "collapsed": false @@ -196,58 +192,6 @@ "outputs": [], "execution_count": null }, - { - "cell_type": "markdown", - "source": [ - "#### 2.2. Create the cluster" - ], - "metadata": { - "collapsed": false - }, - "id": "10799f3efede924d" - }, - { - "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.nanoparticle import create_nanoparticle\n", - "\n", - "cluster = create_nanoparticle(config)" - ], - "metadata": { - "collapsed": false - }, - "id": "a990fa35742d7269", - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Set lattice to Cubic" - ], - "metadata": { - "collapsed": false - }, - "id": "a01018588e6e55fc" - }, - { - "cell_type": "code", - "source": [ - "from mat3ra.made.lattice import Lattice\n", - "\n", - "current_vector_1, current_vector_2, current_vector_3 = cluster.lattice.vectors\n", - "cubic_vector_1 = [current_vector_1[0], 0, 0]\n", - "cubic_vector_2 = [0, current_vector_2[1], 0]\n", - "cubic_vector_3 = [0, 0, current_vector_3[2]]\n", - "cluster.lattice = Lattice.from_vectors_array([cubic_vector_1, cubic_vector_2, cubic_vector_3], type=\"CUB\")" - ], - "metadata": { - "collapsed": false - }, - "id": "4f78c4743b370c3b", - "outputs": [], - "execution_count": null - }, { "cell_type": "markdown", "source": [ diff --git a/other/materials_designer/create_cluster_specific_shape.ipynb b/other/materials_designer/create_cluster_specific_shape.ipynb index 7e4190005..a87886304 100644 --- a/other/materials_designer/create_cluster_specific_shape.ipynb +++ b/other/materials_designer/create_cluster_specific_shape.ipynb @@ -48,7 +48,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -65,6 +64,7 @@ "collapsed": false }, "id": "d9e6be14343d00a1", + "outputs": [], "execution_count": null }, { @@ -80,11 +80,10 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.nanoparticle.enums import ASENanoparticleShapesEnum\n", + "from mat3ra.made.tools.build.nanoparticle.enums import NanoparticleShapesEnum\n", "\n", - "shape = ASENanoparticleShapesEnum.OCTAHEDRON\n", + "shape = NanoparticleShapesEnum.OCTAHEDRON\n", "parameters = {\n", " \"length\": 5,\n", " \"cutoff\": 2\n", @@ -94,6 +93,7 @@ "collapsed": false }, "id": "9d8b1890b34d850a", + "outputs": [], "execution_count": null }, { @@ -108,7 +108,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -118,13 +117,14 @@ "collapsed": false }, "id": "be38fdda1984c654", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", "source": [ "## 2. Create the Target Material\n", - "### 2.1. Set the cluster configuration\n" + "\n" ], "metadata": { "collapsed": false @@ -133,46 +133,20 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.nanoparticle import ASEBasedNanoparticleConfiguration, ASEBasedNanoparticleBuilder\n", + "from mat3ra.made.tools.build.nanoparticle.helpers import create_nanoparticle_by_shape\n", "\n", - "config = ASEBasedNanoparticleConfiguration(\n", - " material=materials[0],\n", + "cluster = create_nanoparticle_by_shape(\n", + " crystal=materials[0],\n", " shape=shape,\n", " parameters=parameters\n", - ")\n", - "\n", - "builder = ASEBasedNanoparticleBuilder()\n" - ], - "metadata": { - "collapsed": false - }, - "id": "8fbe260fa14db47a", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "#### 2.2. Create the cluster" - ], - "metadata": { - "collapsed": false - }, - "id": "10799f3efede924d" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "from mat3ra.made.tools.build.nanoparticle import create_nanoparticle\n", - "\n", - "cluster = create_nanoparticle(config, builder)" + ")" ], "metadata": { "collapsed": false }, "id": "a990fa35742d7269", + "outputs": [], "execution_count": null }, { @@ -187,16 +161,16 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials\n", "\n", - "visualize_materials([{\"material\": cluster}, {\"material\": cluster, \"rotation\": \"-90x\"}])" + "visualize_materials([{\"material\": cluster}, {\"material\": cluster, \"rotation\": \"-90x\"}],viewer=\"wave\")" ], "metadata": { "collapsed": false }, "id": "509b18661a069e42", + "outputs": [], "execution_count": null }, { @@ -211,7 +185,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", @@ -222,6 +195,7 @@ "collapsed": false }, "id": "61daa5afcbc078a9", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_grain_boundary_crystal.ipynb b/other/materials_designer/create_grain_boundary_crystal.ipynb index fa6930136..2a6bf3e4c 100644 --- a/other/materials_designer/create_grain_boundary_crystal.ipynb +++ b/other/materials_designer/create_grain_boundary_crystal.ipynb @@ -56,39 +56,37 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "# Enable interactive selection of terminations via UI prompt\n", - "IS_TERMINATIONS_SELECTION_INTERACTIVE = False \n", + "\n", + "from mat3ra.made.tools.build.slab.termination_utils import select_slab_termination\n", + "\n", "\n", "# Parameters for Phase 1\n", "PHASE_1_MILLER_INDICES = (1, 1, 1)\n", - "PHASE_1_THICKNESS = 6 # in atomic layers\n", - "PHASE_1_USE_ORTHOGONAL_Z = True\n", + "PHASE_1_THICKNESS = 2 # in atomic layers\n", + "PHASE_1_TERMINATION_FORMULA = None # if None, the first termination will be used\n", + "PHASE_1_USE_ORTHOGONAL_C = True\n", "\n", "# Parameters for Phase 2\n", "PHASE_2_MILLER_INDICES = (0, 0, 1)\n", - "PHASE_2_THICKNESS = 4 # in atomic layers\n", - "PHASE_2_USE_ORTHOGONAL_Z = True\n", + "PHASE_2_THICKNESS = 2 # in atomic layers\n", + "PHASE_2_TERMINATION_FORMULA = None # if None, the first termination will be used\n", + "PHASE_2_USE_ORTHOGONAL_C = True\n", "\n", "INTERPHASE_GAP = 2.0 # in Angstrom\n", + "TRANSLATION_VECTOR = [0.0, 0.0, 0.0] # Translation vector for the phase 2 slab relative to phase 1 slab\n", "\n", "# Maximum area for the superlattice search algorithm\n", - "MAX_AREA = 100 # in Angstrom^2\n", + "MAX_AREA = 350 # in Angstrom^2\n", "\n", - "# Parameters for the final material\n", - "SLAB_MILLER_INDICES = (0,0,1)\n", - "SLAB_THICKNESS = 4 # in atomic layers\n", - "SLAB_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "SLAB_VACUUM = 20.0 # in Angstrom\n", - "\n", - "# Set the termination pair indices\n", - "TERMINATION_PAIR_INDEX = 0 # Will be overridden if interactive selection is used" + "# index of the grain boundary to select after strain matching\n", + "MATCH_ID = 0 # if None, the grain boundary with the lowest strain will be selected" ], "metadata": { "collapsed": false }, "id": "38eac66e44951f88", + "outputs": [], "execution_count": null }, { @@ -104,22 +102,23 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", "if sys.platform == \"emscripten\":\n", " import micropip\n", - " \n", + "\n", " await micropip.install('mat3ra-api-examples', deps=False)\n", " await micropip.install('mat3ra-utils')\n", " from mat3ra.utils.jupyterlite.packages import install_packages\n", + "\n", " await install_packages(\"create_grain_boundary.ipynb\")\n" ], "metadata": { "collapsed": false }, "id": "26c1a6af762eda56", + "outputs": [], "execution_count": null }, { @@ -134,7 +133,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -145,6 +143,7 @@ "collapsed": false }, "id": "c269a9fe44c400be", + "outputs": [], "execution_count": null }, { @@ -159,15 +158,16 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", + "\n", "visualize([material], repetitions=[3, 3, 1], rotation=\"0x\")" ], "metadata": { "collapsed": false }, "id": "4fb3d10f24145759", + "outputs": [], "execution_count": null }, { @@ -176,7 +176,7 @@ "## 2. Configure slabs and select termination pair\n", "\n", "### 2.1. Create Phase 1 and Phase 2 Slabs\n", - "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations." + "Get the terminations for the two slabs of phases." ], "metadata": { "collapsed": false @@ -185,144 +185,79 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n", + "from mat3ra.made.tools.build.slab.helpers import get_slab_terminations\n", "\n", - "phase_1_configuration = SlabConfiguration(\n", - " bulk=material,\n", + "phase_1_terminations = get_slab_terminations(\n", + " material=material,\n", " miller_indices=PHASE_1_MILLER_INDICES,\n", - " number_of_layers=PHASE_1_THICKNESS,\n", - " use_orthogonal_z=PHASE_1_USE_ORTHOGONAL_Z\n", ")\n", "\n", - "phase_2_configuration = SlabConfiguration(\n", - " bulk=material,\n", + "phase_2_terminations = get_slab_terminations(\n", + " material=material,\n", " miller_indices=PHASE_2_MILLER_INDICES,\n", - " number_of_layers=PHASE_2_THICKNESS,\n", - " use_orthogonal_z=PHASE_2_USE_ORTHOGONAL_Z\n", ")" ], "metadata": { "collapsed": false }, "id": "70ce21f35a487b63", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Get possible terminations for the slabs" - ], - "metadata": { - "collapsed": false - }, - "id": "b8d50734bdf9ace5" - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "phase_1_terminations = get_terminations(phase_1_configuration)\n", - "phase_2_terminations = get_terminations(phase_2_configuration)" - ], - "metadata": { - "collapsed": false - }, - "id": "af9c0e6d4daebe86", "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.3. Visualize slabs for all possible terminations" - ], - "metadata": { - "collapsed": false - }, + "source": "### 2.3. Visualize slabs for all possible terminations", "id": "d233c1437eb21960" }, { - "cell_type": "code", - "outputs": [], - "source": [ - "phase_1_slabs = [create_slab(phase_1_configuration, termination) for termination in phase_1_terminations]\n", - "phase_2_slabs = [create_slab(phase_2_configuration, termination) for termination in phase_2_terminations]\n", - "\n", - "visualize([{\"material\":slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in phase_1_slabs], repetitions=[3, 3, 1], rotation=\"-90x\")\n", - "visualize([{\"material\":slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in phase_2_slabs], repetitions=[3, 3, 1], rotation=\"-90x\")" - ], - "metadata": { - "collapsed": false - }, - "id": "cd8e53c68e1c7569", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.4. Print terminations for the grain boundary" - ], "metadata": { "collapsed": false }, - "id": "c0ea66b533438153" - }, - { "cell_type": "code", - "outputs": [], "source": [ - "from itertools import product\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", + "from mat3ra.made.tools.analyze.lattice_planes import CrystalLatticePlanesMaterialAnalyzer\n", + "\n", + "phase_1_slabs = [create_slab(material, miller_indices=PHASE_1_MILLER_INDICES, termination=termination) for termination in\n", + " phase_1_terminations]\n", + "\n", + "phase_2_slabs = [create_slab(material, miller_indices=PHASE_2_MILLER_INDICES, termination=termination) for termination in\n", + " phase_2_terminations]\n", "\n", - "termination_pairs = list(product(phase_1_terminations, phase_2_terminations)) \n", - "print(\"Termination Pairs (Phase 1, Phase 2)\")\n", - "for idx, termination_pair in enumerate(termination_pairs):\n", - " print(f\" {idx}: {termination_pair}\")" + "phase_1_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in\n", + " zip(phase_1_slabs, phase_1_terminations)]\n", + "phase_2_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in\n", + " zip(phase_2_slabs, phase_2_terminations)]\n", + "\n", + "visualize(phase_1_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")\n", + "visualize(phase_2_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "317faa88e021deea", + "id": "cd8e53c68e1c7569", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.5. Select termination pair for the grain boundary" - ], - "metadata": { - "collapsed": false - }, + "source": "### 2.4. Select terminations for the grain boundary phases", "id": "5fd99a07e51380b0" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ - "from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n", - "\n", - "termination_pair_index = TERMINATION_PAIR_INDEX\n", - "\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=\"phase 1/phase 2 termination pair\")\n", - " else:\n", - " termination_pair = ui_prompt_select_array_element_by_index(termination_pairs, element_name=\"phase 1/phase 2 termination pair\")" + "phase_1_selected_termination = select_slab_termination(phase_1_terminations, PHASE_1_TERMINATION_FORMULA)\n", + "phase_2_selected_termination = select_slab_termination(phase_2_terminations, PHASE_2_TERMINATION_FORMULA)" ], - "metadata": { - "collapsed": false - }, - "id": "f7c932fb0e2b5086", + "id": "9109ac095608d82a", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 3. Create grain boundary\n", - "\n", - "### 3.1. Initialize the Grain Boundary Configuration" - ], + "source": "## 3. Create grain boundary", "metadata": { "collapsed": false }, @@ -330,89 +265,27 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.grain_boundary import SlabGrainBoundaryConfiguration\n", - "\n", - "phase_1_termination, phase_2_termination = termination_pair\n", - "\n", - "# Create a slab configuration for the final grain boundary structure\n", - "slab_configuration = SlabConfiguration(\n", - " bulk=material,\n", - " miller_indices=SLAB_MILLER_INDICES,\n", - " number_of_layers=SLAB_THICKNESS,\n", - " vacuum=SLAB_VACUUM,\n", - ")\n", + "from mat3ra.made.tools.build.grain_boundary.helpers import create_grain_boundary_planar\n", "\n", - "grain_boundary_configuration = SlabGrainBoundaryConfiguration(\n", - " phase_1_configuration=phase_1_configuration,\n", - " phase_2_configuration=phase_2_configuration,\n", - " phase_1_termination=phase_1_termination,\n", - " phase_2_termination=phase_2_termination,\n", + "grain_boundary = create_grain_boundary_planar(\n", + " phase_1_material=material,\n", + " phase_1_miller_indices=PHASE_1_MILLER_INDICES,\n", + " phase_2_miller_indices=PHASE_2_MILLER_INDICES,\n", + " phase_1_thickness=PHASE_1_THICKNESS,\n", + " phase_2_thickness=PHASE_2_THICKNESS,\n", " gap=INTERPHASE_GAP,\n", - " slab_configuration=slab_configuration\n", - ")" - ], - "metadata": { - "collapsed": false - }, - "id": "e9977c17f97f0035", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 3.2. Set Strain Matching Algorithm Parameters" - ], - "metadata": { - "collapsed": false - }, - "id": "8d647c5ed5401b55" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "from mat3ra.made.tools.build.interface import ZSLStrainMatchingParameters\n", - "from mat3ra.made.tools.build.grain_boundary.builders import SlabGrainBoundaryBuilderParameters\n", - "\n", - "zsl_strain_matching_parameters = ZSLStrainMatchingParameters(\n", - " max_area=MAX_AREA\n", - ")\n", - "\n", - "builder_parameters = SlabGrainBoundaryBuilderParameters(\n", - " strain_matching_parameters=zsl_strain_matching_parameters\n", + " translation_vector=TRANSLATION_VECTOR,\n", + " max_area=MAX_AREA,\n", + " max_area_ratio_tol=0.2,\n", + " match_id =MATCH_ID,\n", ")\n" ], "metadata": { "collapsed": false }, - "id": "f1eb5313cda0d05b", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 3.3. Generate grain boundary with strain matcher" - ], - "metadata": { - "collapsed": false - }, - "id": "48ba06b5baf7d0b5" - }, - { - "cell_type": "code", + "id": "e9977c17f97f0035", "outputs": [], - "source": [ - "from mat3ra.made.tools.build.grain_boundary import SlabGrainBoundaryBuilder\n", - "\n", - "grain_boundary_builder = SlabGrainBoundaryBuilder(build_parameters=builder_parameters)\n", - "grain_boundary = grain_boundary_builder.get_material(configuration=grain_boundary_configuration)" - ], - "metadata": { - "collapsed": false - }, - "id": "ec2864bde87580b7", "execution_count": null }, { @@ -427,7 +300,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "visualize([grain_boundary], repetitions=[1, 1, 1])\n", "visualize([grain_boundary], repetitions=[1, 1, 1], rotation=\"-90x\")" @@ -436,6 +308,7 @@ "collapsed": false }, "id": "abd081a986bdca0", + "outputs": [], "execution_count": null }, { @@ -450,15 +323,16 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", + "\n", "set_materials(grain_boundary)" ], "metadata": { "collapsed": false }, "id": "76469e88bd21a25d", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_grain_boundary_film.ipynb b/other/materials_designer/create_grain_boundary_film.ipynb index 2a501ebb7..973028216 100644 --- a/other/materials_designer/create_grain_boundary_film.ipynb +++ b/other/materials_designer/create_grain_boundary_film.ipynb @@ -48,15 +48,16 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "# Material selection\n", - "MATERIAL_INDEX = 0 # Index in the list of materials\n", + "MATERIAL_INDEX = 1 # Index in the list of materials\n", "\n", "# Grain boundary parameters\n", "TARGET_TWIST_ANGLE = 17.9 # in degrees\n", "BOUNDARY_GAP = 2.0 # Gap between two orientations in X direction, in Angstroms\n", "XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]] # Supercell matrix to be applied to each of the orientations before matching\n", + "MILLER_INDICES = (0, 0, 1) # Miller indices for the supercell matching\n", + "VACUUM = 10.0 # Vacuum thickness in Angstroms, added to the top and bottom of the grain boundary\n", "\n", "# Search algorithm parameters\n", "MAX_REPETITION = 6 # Maximum supercell matrix element value\n", @@ -80,6 +81,7 @@ "collapsed": false }, "id": "338ee3c51155e086", + "outputs": [], "execution_count": null }, { @@ -95,7 +97,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -112,6 +113,7 @@ "collapsed": false }, "id": "7e22d1f4da825575", + "outputs": [], "execution_count": null }, { @@ -126,7 +128,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -136,6 +137,7 @@ "collapsed": false }, "id": "a1635c31132962f6", + "outputs": [], "execution_count": null }, { @@ -151,7 +153,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials\n", "\n", @@ -164,14 +165,12 @@ "collapsed": false }, "id": "61f0870d8104cd21", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 3. Generate Surface Grain Boundary\n", - "### 3.1. Set up grain boundary configuration and builder\n" - ], + "source": "## 3. Generate Surface Grain Boundary\n", "metadata": { "collapsed": false }, @@ -179,78 +178,32 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.grain_boundary import (\n", - " SurfaceGrainBoundaryConfiguration,\n", - " SurfaceGrainBoundaryBuilderParameters,\n", - " SurfaceGrainBoundaryBuilder\n", - ")\n", - "\n", - "config = SurfaceGrainBoundaryConfiguration(\n", - " film=material,\n", - " twist_angle=TARGET_TWIST_ANGLE,\n", - " distance_z=BOUNDARY_GAP,\n", - " gap=BOUNDARY_GAP,\n", - " xy_supercell_matrix=XY_SUPERCELL_MATRIX\n", - ")\n", + "from mat3ra.esse.models.core.reusable.axis_enum import AxisEnum\n", + "from mat3ra.made.tools.build.grain_boundary import create_grain_boundary_linear\n", "\n", - "params = SurfaceGrainBoundaryBuilderParameters(\n", - " max_supercell_matrix_int=MAX_REPETITION,\n", - " angle_tolerance=ANGLE_TOLERANCE,\n", - " return_first_match=RETURN_FIRST_MATCH,\n", - " edge_inclusion_tolerance=EDGE_INCLUSION_TOLERANCE,\n", - " distance_tolerance=DISTANCE_TOLERANCE\n", - ")\n", "\n", - "builder = SurfaceGrainBoundaryBuilder(build_parameters=params)" + "grain_boundary = create_grain_boundary_linear(\n", + " material=material,\n", + " target_angle=TARGET_TWIST_ANGLE,\n", + " angle_tolerance=EDGE_INCLUSION_TOLERANCE,\n", + " max_repetition_int=MAX_REPETITION,\n", + " direction=AxisEnum.x,\n", + " gap=BOUNDARY_GAP,\n", + " miller_indices=MILLER_INDICES,\n", + " vacuum=VACUUM\n", + ")\n" ], "metadata": { "collapsed": false }, "id": "33a2c8a9be436745", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 3.2. Generate and analyze grain boundaries\n" - ], - "metadata": { - "collapsed": false - }, - "id": "79e9378bf5e144d4" - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "from utils.plot import plot_twisted_interface_solutions\n", - "\n", - "grain_boundaries = builder.get_materials(config)\n", - "\n", - "print(f\"\\nFound {len(grain_boundaries)} possible structures\")\n", - "for i, gb in enumerate(grain_boundaries):\n", - " actual_angle = gb.metadata.get(\"actual_twist_angle\", \"unknown\")\n", - " print(f\"\\nGrain Boundary {i + 1}:\")\n", - " print(f\"Actual twist angle: {actual_angle}°\")\n", - " print(f\"Number of atoms: {len(gb.basis.elements.ids)}\")\n", - "\n", - "if len(grain_boundaries) > 0:\n", - " plot_twisted_interface_solutions(grain_boundaries)" - ], - "metadata": { - "collapsed": false - }, - "id": "d7007fe825463e5a", "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 4. Preview the selected grain boundary\n", - "By default, the first grain boundary is selected. You can change the selection by changing the `selected_structure` index." - ], + "source": "## 4. Preview grain boundary", "metadata": { "collapsed": false }, @@ -258,21 +211,21 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "selected_structure = grain_boundaries[0]\n", - "actual_angle = selected_structure.metadata.get(\"build\").get(\"configuration\").get(\"actual_twist_angle\")\n", + "actual_angle = grain_boundary.metadata.build[-1].configuration.get(\"actual_angle\")\n", + "print(actual_angle)\n", "print(f\"Target angle: {TARGET_TWIST_ANGLE}°\")\n", "print(f\"Actual angle: {actual_angle}°\")\n", - "print(f\"Number of atoms: {len(selected_structure.basis.elements.ids)}\")\n", + "print(f\"Number of atoms: {len(grain_boundary.basis.elements.ids)}\")\n", "\n", - "visualize_materials(selected_structure, repetitions=[1, 1, 1])\n", - "visualize_materials(selected_structure, repetitions=[1, 1, 1], rotation=\"-90x\")" + "visualize_materials(grain_boundary, repetitions=[1, 1, 1])\n", + "visualize_materials(grain_boundary, repetitions=[1, 1, 1], rotation=\"-90x\")" ], "metadata": { "collapsed": false }, "id": "7f558a8e9d417cef", + "outputs": [], "execution_count": null }, { @@ -287,16 +240,16 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", - "set_materials(selected_structure)" + "set_materials(grain_boundary)" ], "metadata": { "collapsed": false }, "id": "20e46167358d63", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_heterostructure_example.ipynb b/other/materials_designer/create_heterostructure_example.ipynb index d90c2f213..009a6b195 100644 --- a/other/materials_designer/create_heterostructure_example.ipynb +++ b/other/materials_designer/create_heterostructure_example.ipynb @@ -2,6 +2,10 @@ "cells": [ { "cell_type": "markdown", + "id": "ad0a4601cb4095ad", + "metadata": { + "collapsed": false + }, "source": [ "# Create Heterostructure Example with Three Materials\n", "\n", @@ -26,28 +30,27 @@ "1. For more information, see [Introduction](Introduction.ipynb)\n", "\n", "\n" - ], - "metadata": { - "collapsed": false - }, - "id": "ad0a4601cb4095ad" + ] }, { "cell_type": "markdown", + "id": "a0b4736f3dffa189", + "metadata": { + "collapsed": false + }, "source": [ "## 1. Prepare the Environment\n", "### 1.1. Set up the Notebook\n", "\n", "Set the following flags to control the notebook behavior.\n" - ], - "metadata": { - "collapsed": false - }, - "id": "a0b4736f3dffa189" + ] }, { "cell_type": "code", - "outputs": [], + "id": "9e90252bcef065c9", + "metadata": { + "collapsed": false + }, "source": [ "# Enable interactive selection of terminations via UI prompt\n", "IS_TERMINATIONS_SELECTION_INTERACTIVE = False \n", @@ -69,47 +72,47 @@ "MATERIAL_0_THICKNESS = 3 # in atomic layers\n", "MATERIAL_0_VACUUM = 3 # in Angstroms\n", "MATERIAL_0_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "MATERIAL_0_USE_ORTHOGONAL_Z = True\n", + "MATERIAL_0_USE_ORTHOGONAL_C = True\n", "\n", "# Configuration for Material 1 (Film 1)\n", "MATERIAL_1_MILLER_INDICES = (0, 0, 1)\n", "MATERIAL_1_THICKNESS = 1 # in atomic layers\n", "MATERIAL_1_VACUUM = 0 # in Angstroms\n", "MATERIAL_1_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "MATERIAL_1_USE_ORTHOGONAL_Z = True\n", + "MATERIAL_1_USE_ORTHOGONAL_C = True\n", "\n", "# Configuration for Material 2 (Film 2)\n", "MATERIAL_2_MILLER_INDICES = (0, 0, 1)\n", "MATERIAL_2_THICKNESS = 1 # in atomic layers\n", "MATERIAL_2_VACUUM = 1 # in Angstroms\n", "MATERIAL_2_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "MATERIAL_2_USE_ORTHOGONAL_Z = True\n", + "MATERIAL_2_USE_ORTHOGONAL_C = True\n", "\n", "# Set termination pair indices for both interfaces\n", "TERMINATION_PAIR_INDEX_01 = 0\n", "TERMINATION_PAIR_INDEX_12 = 0\n" ], - "metadata": { - "collapsed": false - }, - "id": "9e90252bcef065c9", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", + "id": "e460756f40327e78", + "metadata": { + "collapsed": false + }, "source": [ "### 1.2. Install Packages\n", "\n", "The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb)).\n" - ], - "metadata": { - "collapsed": false - }, - "id": "e460756f40327e78" + ] }, { "cell_type": "code", - "outputs": [], + "id": "a4d99b5b40274810", + "metadata": { + "collapsed": false + }, "source": [ "import sys\n", "\n", @@ -120,27 +123,27 @@ " from mat3ra.utils.jupyterlite.packages import install_packages\n", " await install_packages(\"create_interface_with_min_strain_zsl.ipynb\")\n" ], - "metadata": { - "collapsed": false - }, - "id": "a4d99b5b40274810", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", + "id": "c4b29abaa6160a66", + "metadata": { + "collapsed": false + }, "source": [ "### 1.3. Get Input Materials and Assign `material0`, `material1`, and `material2`\n", "\n", "Materials are loaded with `get_materials()`. The first material is assigned as **Material 0**, the second as **Material 1**, and the third as **Material 2**.\n" - ], - "metadata": { - "collapsed": false - }, - "id": "c4b29abaa6160a66" + ] }, { "cell_type": "code", - "outputs": [], + "id": "e90d5bf2655f5e0f", + "metadata": { + "collapsed": false + }, "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -160,117 +163,117 @@ " print(\"Please select Material 2. Material 2 is set to Material 0.\")\n", " material2 = material0\n" ], - "metadata": { - "collapsed": false - }, - "id": "e90d5bf2655f5e0f", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", + "id": "1ffc1f88eedbc9a4", + "metadata": { + "collapsed": false + }, "source": [ "### 1.4. Preview Original Materials\n", "\n", "Visualize the three original materials.\n" - ], - "metadata": { - "collapsed": false - }, - "id": "1ffc1f88eedbc9a4" + ] }, { "cell_type": "code", - "outputs": [], + "id": "6253034909a0fef9", + "metadata": { + "collapsed": false + }, "source": [ "from utils.visualize import visualize_materials as visualize\n", "\n", "visualize([material0, material1, material2], repetitions=[3, 3, 1], rotation=\"0x\")\n" ], - "metadata": { - "collapsed": false - }, - "id": "6253034909a0fef9", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", + "id": "574327eaccdd52f0", + "metadata": { + "collapsed": false + }, "source": [ "## 2. Create First Interface (Material 0 + Material 1)\n", "\n", "### 2.1. Configure Slabs and Select Termination Pair\n", "\n", "Set up slab configurations for **Material 0** and **Material 1**, then select terminations for the first interface.\n" - ], - "metadata": { - "collapsed": false - }, - "id": "574327eaccdd52f0" + ] }, { "cell_type": "code", - "outputs": [], + "id": "de4fe773ee9c8a61", + "metadata": { + "collapsed": false + }, "source": [ - "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n", + "from mat3ra.made.tools.build.slab.helpers import get_slab_terminations\n", + "from mat3ra.made.tools.build.slab.configurations import SlabConfiguration\n", "\n", - "# Slab Configuration for Material 1\n", - "material1_slab_configuration = SlabConfiguration(\n", - " bulk=material1,\n", + "# Slab Configuration for Material 1 (Film) - using correct parameters like ZSL notebook\n", + "material1_slab_configuration = SlabConfiguration.from_parameters(\n", + " material_or_dict=material1,\n", " miller_indices=MATERIAL_1_MILLER_INDICES,\n", " number_of_layers=MATERIAL_1_THICKNESS, # in atomic layers\n", " vacuum=MATERIAL_1_VACUUM, # in Angstroms\n", - " xy_supercell_matrix=MATERIAL_1_XY_SUPERCELL_MATRIX,\n", - " use_orthogonal_z=MATERIAL_1_USE_ORTHOGONAL_Z\n", + " termination_formula=None, # if None, the first termination will be used\n", + " use_conventional_cell=True\n", ")\n", "\n", - "# Slab Configuration for Material 0 (Substrate)\n", - "material0_slab_configuration = SlabConfiguration(\n", - " bulk=material0,\n", + "# Slab Configuration for Material 0 (Substrate) - using correct parameters like ZSL notebook\n", + "material0_slab_configuration = SlabConfiguration.from_parameters(\n", + " material_or_dict=material0,\n", " miller_indices=MATERIAL_0_MILLER_INDICES,\n", " number_of_layers=MATERIAL_0_THICKNESS, # in atomic layers\n", " vacuum=MATERIAL_0_VACUUM, # in Angstroms\n", - " xy_supercell_matrix=MATERIAL_0_XY_SUPERCELL_MATRIX,\n", - " use_orthogonal_z=MATERIAL_0_USE_ORTHOGONAL_Z\n", + " termination_formula=None, # if None, the first termination will be used\n", + " use_conventional_cell=True\n", ")\n", "\n", "# Get possible terminations for the slabs\n", - "material1_slab_terminations = get_terminations(material1_slab_configuration)\n", - "material0_slab_terminations = get_terminations(material0_slab_configuration)\n", + "material1_slab_terminations = get_slab_terminations(material=material1, miller_indices=MATERIAL_1_MILLER_INDICES)\n", + "material0_slab_terminations = get_slab_terminations(material=material0, miller_indices=MATERIAL_0_MILLER_INDICES)\n", "\n", - "# Visualize all possible terminations\n", - "material1_slabs = [create_slab(material1_slab_configuration, termination) for termination in material1_slab_terminations]\n", - "material0_slabs = [create_slab(material0_slab_configuration, termination) for termination in material0_slab_terminations]\n", + "# Visualize all possible terminations using analyzer approach\n", + "from mat3ra.made.tools.analyze.lattice_planes import CrystalLatticePlanesMaterialAnalyzer\n", "\n", - "visualize(\n", - " [{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in material1_slabs],\n", - " repetitions=[3, 3, 1],\n", - " rotation=\"-90x\"\n", - ")\n", + "material1_analyzer = CrystalLatticePlanesMaterialAnalyzer(material=material1, miller_indices=MATERIAL_1_MILLER_INDICES)\n", + "material1_slabs = [material1_analyzer.get_material_with_termination_without_vacuum(termination) for termination in material1_slab_terminations]\n", + "\n", + "material0_analyzer = CrystalLatticePlanesMaterialAnalyzer(material=material0, miller_indices=MATERIAL_0_MILLER_INDICES)\n", + "material0_slabs = [material0_analyzer.get_material_with_termination_without_vacuum(termination) for termination in material0_slab_terminations]\n", "\n", - "visualize(\n", - " [{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in material0_slabs],\n", - " repetitions=[3, 3, 1],\n", - " rotation=\"-90x\"\n", - ")\n" + "material1_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in zip(material1_slabs, material1_slab_terminations)]\n", + "material0_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in zip(material0_slabs, material0_slab_terminations)]\n", + "\n", + "visualize(material1_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")\n", + "visualize(material0_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")\n" ], - "metadata": { - "collapsed": false - }, - "id": "de4fe773ee9c8a61", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.2. Print and Select Termination Pair for First Interface\n" - ], + "id": "e4aea26afab84e0c", "metadata": { "collapsed": false }, - "id": "e4aea26afab84e0c" + "source": [ + "### 2.2. Print and Select Termination Pair for First Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "4e467693b61f0125", + "metadata": { + "collapsed": false + }, "source": [ "from itertools import product\n", "\n", @@ -279,32 +282,40 @@ "for idx, termination_pair in enumerate(termination_pairs_01):\n", " print(f\" {idx}: {termination_pair}\")\n" ], - "metadata": { - "collapsed": false - }, - "id": "4e467693b61f0125", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.3. Select Termination Pair for First Interface\n" - ], + "id": "e70e2a4ef133c9f", "metadata": { "collapsed": false }, - "id": "e70e2a4ef133c9f" + "source": [ + "### 2.3. Select Termination Pair for First Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "c99cb2e5bbcd24df", + "metadata": { + "collapsed": false + }, "source": [ + "from mat3ra.made.tools.build.slab.termination_utils import select_slab_termination\n", "from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n", "\n", - "termination_pair_index_01 = TERMINATION_PAIR_INDEX_01\n", + "# Select terminations for each material using the newer approach\n", + "material1_termination = select_slab_termination(material1_slab_terminations, None) # None means use first termination\n", + "material0_termination = select_slab_termination(material0_slab_terminations, None) # None means use first termination\n", "\n", - "termination_pair_first = termination_pairs_01[termination_pair_index_01]\n", + "# Create termination pair\n", + "termination_pair_first = (material1_termination, material0_termination)\n", + "\n", + "# Allow for interactive selection if enabled\n", "if IS_TERMINATIONS_SELECTION_INTERACTIVE:\n", + " termination_pair_index_01 = TERMINATION_PAIR_INDEX_01\n", + " termination_pair_first = termination_pairs_01[termination_pair_index_01]\n", " if sys.platform == \"emscripten\":\n", " termination_pair_first = await ui_prompt_select_array_element_by_index_pyodide(\n", " termination_pairs_01,\n", @@ -316,94 +327,111 @@ " element_name=\"Material1/Material0 termination pair\"\n", " )\n" ], - "metadata": { - "collapsed": false - }, - "id": "c99cb2e5bbcd24df", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.4. Initialize Interface Configuration for First Interface\n" - ], + "id": "7621d2178a91c691", "metadata": { "collapsed": false }, - "id": "7621d2178a91c691" + "source": [ + "### 2.4. Initialize Interface Configuration for First Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "9e87ca9779cee593", + "metadata": { + "collapsed": false + }, "source": [ - "from mat3ra.made.tools.build.interface import InterfaceConfiguration\n", + "from mat3ra.made.tools.build.slab.builders import SlabBuilder\n", "\n", + "# Create actual slabs using the newer approach\n", "material1_termination, material0_termination = termination_pair_first\n", - "interface_configuration_01 = InterfaceConfiguration(\n", - " film_configuration=material1_slab_configuration,\n", - " substrate_configuration=material0_slab_configuration,\n", - " film_termination=material1_termination,\n", - " substrate_termination=material0_termination,\n", - " distance=INTERFACE_01_DISTANCE,\n", - " vacuum=FINAL_INTERFACE_VACUUM\n", - ")\n" + "\n", + "# Update configurations with selected terminations - using correct parameters like ZSL notebook\n", + "material1_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=material1,\n", + " miller_indices=MATERIAL_1_MILLER_INDICES,\n", + " number_of_layers=MATERIAL_1_THICKNESS,\n", + " vacuum=0.0, # Set vacuum to 0 for interface creation\n", + " termination_formula=None, # Will use selected termination\n", + " use_conventional_cell=True\n", + ")\n", + "\n", + "material0_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=material0,\n", + " miller_indices=MATERIAL_0_MILLER_INDICES,\n", + " number_of_layers=MATERIAL_0_THICKNESS,\n", + " vacuum=0.0, # Set vacuum to 0 for interface creation\n", + " termination_formula=None, # Will use selected termination\n", + " use_conventional_cell=True\n", + ")\n", + "\n", + "# Build the actual slabs\n", + "material1_slab = SlabBuilder().get_material(material1_slab_config)\n", + "material0_slab = SlabBuilder().get_material(material0_slab_config)\n" ], - "metadata": { - "collapsed": false - }, - "id": "9e87ca9779cee593", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.5. Set Strain Matching Parameters and Generate First Interface\n" - ], + "id": "afab24f1d8cf9ad7", "metadata": { "collapsed": false }, - "id": "afab24f1d8cf9ad7" + "source": [ + "### 2.5. Set Strain Matching Parameters and Generate First Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "9b72198198a18278", + "metadata": { + "collapsed": false + }, "source": [ - "from mat3ra.made.tools.build.interface import ZSLStrainMatchingParameters\n", - "from mat3ra.made.tools.build.interface import ZSLStrainMatchingInterfaceBuilder, ZSLStrainMatchingInterfaceBuilderParameters\n", + "from mat3ra.made.tools.analyze.interface import ZSLInterfaceAnalyzer\n", "\n", - "zsl_strain_matching_parameters_01 = ZSLStrainMatchingParameters(\n", - " max_area=MAX_AREA_01\n", + "# Set up ZSL Interface Analyzer with the newer approach\n", + "zsl_analyzer_01 = ZSLInterfaceAnalyzer(\n", + " substrate_slab_configuration=material0_slab_config,\n", + " film_slab_configuration=material1_slab_config,\n", + " max_area=MAX_AREA_01,\n", + " max_area_ratio_tol=0.09, # Default tolerance\n", + " max_angle_tol=0.03, # Default tolerance\n", + " max_length_tol=0.03 # Default tolerance\n", ")\n", "\n", - "matched_interfaces_builder_01 = ZSLStrainMatchingInterfaceBuilder(\n", - " build_parameters=ZSLStrainMatchingInterfaceBuilderParameters(\n", - " strain_matching_parameters=zsl_strain_matching_parameters_01\n", - " )\n", - ")\n", - "\n", - "interfaces_01_sorted = matched_interfaces_builder_01.get_materials(configuration=interface_configuration_01)\n" + "# Get ZSL matches\n", + "matches_01 = zsl_analyzer_01.zsl_match_holders\n" ], - "metadata": { - "collapsed": false - }, - "id": "9b72198198a18278", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.6. Plot and Select First Interface\n" - ], + "id": "4989c48b4ed6a33d", "metadata": { "collapsed": false }, - "id": "4989c48b4ed6a33d" + "source": [ + "### 2.6. Plot and Select First Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "32e05e63fea1b5a3", + "metadata": { + "collapsed": false + }, "source": [ - "from utils.plot import plot_strain_vs_atoms\n", + "from utils.plot import plot_strain_vs_area\n", + "from mat3ra.made.tools.build.interface.helpers import create_zsl_interface_between_slabs\n", "\n", "PLOT_SETTINGS = {\n", " \"HEIGHT\": 600,\n", @@ -411,154 +439,147 @@ " \"Y_SCALE\": \"log\", # or linear\n", "}\n", "\n", - "plot_strain_vs_atoms(interfaces_01_sorted, PLOT_SETTINGS)\n", + "plot_strain_vs_area(matches_01, PLOT_SETTINGS)\n", + "\n", + "# Select the interface with the lowest strain and smallest number of atoms\n", + "selected_index_01 = 0\n", + "\n", + "# Create the first interface using the newer approach\n", + "interface_01 = create_zsl_interface_between_slabs(\n", + " substrate_slab=material0_slab,\n", + " film_slab=material1_slab,\n", + " gap=INTERFACE_01_DISTANCE,\n", + " vacuum=FINAL_INTERFACE_VACUUM,\n", + " match_id=selected_index_01,\n", + " max_area=MAX_AREA_01,\n", + ")\n", "\n", - "# Select the first interface with the lowest strain and smallest number of atoms\n", - "interfaces_slice_range_01 = slice(0, 1)\n", - "selected_interfaces_01 = interfaces_01_sorted[interfaces_slice_range_01]\n" + "selected_interfaces_01 = [interface_01]\n" ], - "metadata": { - "collapsed": false - }, - "id": "32e05e63fea1b5a3", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.7. Preview the First Interface\n" - ], + "id": "342d6261ae79122", "metadata": { "collapsed": false }, - "id": "342d6261ae79122" + "source": [ + "### 2.7. Preview the First Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "1148759314be11cc", + "metadata": { + "collapsed": false + }, "source": [ "visualize(selected_interfaces_01, repetitions=[3, 3, 1])\n", "visualize(selected_interfaces_01, repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "1148759314be11cc", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", + "id": "df770aba2dbc2df0", + "metadata": { + "collapsed": false + }, "source": [ "## 3. Create Second Interface (First Interface + Material 2)\n", "\n", "### 3.1. Configure Slabs and Select Termination Pair for Second Interface\n", "\n", "Now, use the first interface as the substrate to add **Material 2**.\n" - ], - "metadata": { - "collapsed": false - }, - "id": "df770aba2dbc2df0" + ] }, { "cell_type": "code", - "outputs": [], + "id": "636e0e4c45b02925", + "metadata": { + "collapsed": false + }, "source": [ "from mat3ra.made.tools.modify import translate_to_z_level\n", - "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n", "\n", "# Update substrate to be the first interface\n", "substrate_second = translate_to_z_level(selected_interfaces_01[0], \"top\")\n", "\n", - "# Slab Configuration for Material 2\n", - "material2_slab_configuration = SlabConfiguration(\n", - " bulk=material2,\n", - " miller_indices=MATERIAL_2_MILLER_INDICES,\n", - " number_of_layers=MATERIAL_2_THICKNESS, # in atomic layers\n", - " vacuum=MATERIAL_2_VACUUM, # in atomic layers\n", - " xy_supercell_matrix=MATERIAL_2_XY_SUPERCELL_MATRIX,\n", - " use_orthogonal_z=MATERIAL_2_USE_ORTHOGONAL_Z\n", - ")\n", - "\n", - "# Slab Configuration for Substrate (First Interface)\n", - "substrate_second_slab_configuration = SlabConfiguration(\n", - " bulk=substrate_second,\n", - " miller_indices=(0, 0, 1), # Z-orientation for the first interface\n", - " number_of_layers=1, # One unit cell thick\n", - " vacuum=0, \n", - " xy_supercell_matrix=MATERIAL_0_XY_SUPERCELL_MATRIX, # Adjust if necessary\n", - " use_orthogonal_z=MATERIAL_0_USE_ORTHOGONAL_Z\n", - ")\n", + "# Get possible terminations for Material 2 and the substrate (first interface)\n", + "material2_slab_terminations = get_slab_terminations(material=material2, miller_indices=MATERIAL_2_MILLER_INDICES)\n", + "# For the substrate (first interface), we'll use a simple approach since it's already an interface\n", + "substrate_second_slab_terminations = [\"top\"] # Simple termination for the interface substrate\n", "\n", - "# Get possible terminations for the second interface slabs\n", - "material2_slab_terminations = get_terminations(material2_slab_configuration)\n", - "substrate_second_slab_terminations = get_terminations(substrate_second_slab_configuration)\n", + "# Visualize Material 2 terminations using analyzer approach\n", + "material2_analyzer = CrystalLatticePlanesMaterialAnalyzer(material=material2, miller_indices=MATERIAL_2_MILLER_INDICES)\n", + "material2_slabs = [material2_analyzer.get_material_with_termination_without_vacuum(termination) for termination in material2_slab_terminations]\n", "\n", - "# Visualize all possible terminations for Material 2 and Substrate (First Interface)\n", - "material2_slabs = [create_slab(material2_slab_configuration, termination) for termination in material2_slab_terminations]\n", - "substrate_second_slabs = [create_slab(substrate_second_slab_configuration, termination) for termination in substrate_second_slab_terminations]\n", + "material2_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in zip(material2_slabs, material2_slab_terminations)]\n", "\n", - "visualize(\n", - " [{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in material2_slabs],\n", - " repetitions=[3, 3, 1],\n", - " rotation=\"-90x\"\n", - ")\n", + "visualize(material2_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")\n", "\n", - "visualize(\n", - " [{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in substrate_second_slabs],\n", - " repetitions=[3, 3, 1],\n", - " rotation=\"-90x\"\n", - ")" + "# Visualize the substrate (first interface)\n", + "visualize([{\"material\": substrate_second, \"title\": \"First Interface (Substrate)\"}], repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "636e0e4c45b02925", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.2. Print and Select Termination Pair for Second Interface\n" - ], + "id": "ac68ed5b9219b0dc", "metadata": { "collapsed": false }, - "id": "ac68ed5b9219b0dc" + "source": [ + "### 3.2. Print and Select Termination Pair for Second Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "41b3d541c1ebfe5a", + "metadata": { + "collapsed": false + }, "source": [ "termination_pairs_12 = list(product(material2_slab_terminations, substrate_second_slab_terminations)) \n", "print(\"Termination Pairs for Second Interface (Material2, First Interface Substrate)\")\n", "for idx, termination_pair in enumerate(termination_pairs_12):\n", " print(f\" {idx}: {termination_pair}\")" ], - "metadata": { - "collapsed": false - }, - "id": "41b3d541c1ebfe5a", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.3. Select Termination Pair for Second Interface\n" - ], + "id": "822c79480c3d7965", "metadata": { "collapsed": false }, - "id": "822c79480c3d7965" + "source": [ + "### 3.3. Select Termination Pair for Second Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "f9d2b5429447338e", + "metadata": { + "collapsed": false + }, "source": [ - "termination_pair_index_12 = TERMINATION_PAIR_INDEX_12\n", + "# Select terminations for Material 2 and the substrate using the newer approach\n", + "material2_termination = select_slab_termination(material2_slab_terminations, None) # None means use first termination\n", + "substrate_second_termination = substrate_second_slab_terminations[0] # Use the first (and only) termination\n", + "\n", + "# Create termination pair\n", + "termination_pair_second = (material2_termination, substrate_second_termination)\n", "\n", - "termination_pair_second = termination_pairs_12[termination_pair_index_12]\n", + "# Allow for interactive selection if enabled\n", "if IS_TERMINATIONS_SELECTION_INTERACTIVE:\n", + " termination_pair_index_12 = TERMINATION_PAIR_INDEX_12\n", + " termination_pair_second = termination_pairs_12[termination_pair_index_12]\n", " if sys.platform == \"emscripten\":\n", " termination_pair_second = await ui_prompt_select_array_element_by_index_pyodide(\n", " termination_pairs_12,\n", @@ -570,163 +591,191 @@ " element_name=\"Material2/First Interface termination pair\"\n", " )" ], - "metadata": { - "collapsed": false - }, - "id": "f9d2b5429447338e", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.4. Initialize Interface Configuration for Second Interface\n" - ], + "id": "796e3604d6bd4c60", "metadata": { "collapsed": false }, - "id": "796e3604d6bd4c60" + "source": [ + "### 3.4. Initialize Interface Configuration for Second Interface\n" + ] }, { "cell_type": "code", - "outputs": [], - "source": [ - "from mat3ra.made.tools.build.interface import InterfaceConfiguration\n", - "\n", - "material2_termination, substrate_second_termination = termination_pair_second\n", - "interface_configuration_12 = InterfaceConfiguration(\n", - " film_configuration=material2_slab_configuration,\n", - " substrate_configuration=substrate_second_slab_configuration,\n", - " film_termination=material2_termination,\n", - " substrate_termination=substrate_second_termination,\n", - " distance=INTERFACE_12_DISTANCE,\n", - " vacuum=FINAL_INTERFACE_VACUUM\n", - ")" - ], + "id": "fa7e6b937d2b78a0", "metadata": { "collapsed": false }, - "id": "fa7e6b937d2b78a0", + "source": [ + "# Create slab configurations and slabs for the second interface using the newer approach\n", + "material2_termination, substrate_second_termination = termination_pair_second\n", + "\n", + "# Slab configuration for Material 2 - using correct parameters like ZSL notebook\n", + "material2_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=material2,\n", + " miller_indices=MATERIAL_2_MILLER_INDICES,\n", + " number_of_layers=MATERIAL_2_THICKNESS,\n", + " vacuum=0.0, # Set vacuum to 0 for interface creation\n", + " termination_formula=None, # Will use selected termination\n", + " use_conventional_cell=True\n", + ")\n", + "\n", + "# Build the Material 2 slab\n", + "material2_slab = SlabBuilder().get_material(material2_slab_config)\n", + "\n", + "# For the substrate (first interface), we'll use it as-is since it's already built" + ], + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.5. Set Strain Matching Parameters and Generate Second Interface\n" - ], + "id": "3816e1b290f7e5d0", "metadata": { "collapsed": false }, - "id": "3816e1b290f7e5d0" + "source": [ + "### 3.5. Set Strain Matching Parameters and Generate Second Interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "6f30c6961f7abbfe", + "metadata": { + "collapsed": false + }, "source": [ - "zsl_strain_matching_parameters_12 = ZSLStrainMatchingParameters(\n", - " max_area=MAX_AREA_12\n", + "# Set up ZSL Interface Analyzer for the second interface\n", + "# Note: For the second interface, we need to create a slab configuration for the substrate (first interface)\n", + "substrate_second_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=substrate_second,\n", + " miller_indices=(0, 0, 1), # Z-orientation for the first interface\n", + " number_of_layers=1, # One unit cell thick\n", + " vacuum=0.0,\n", + " termination_formula=None,\n", + " use_conventional_cell=True\n", ")\n", "\n", - "matched_interfaces_builder_12 = ZSLStrainMatchingInterfaceBuilder(\n", - " build_parameters=ZSLStrainMatchingInterfaceBuilderParameters(\n", - " strain_matching_parameters=zsl_strain_matching_parameters_12\n", - " )\n", + "zsl_analyzer_12 = ZSLInterfaceAnalyzer(\n", + " substrate_slab_configuration=substrate_second_slab_config,\n", + " film_slab_configuration=material2_slab_config,\n", + " max_area=MAX_AREA_12,\n", + " max_area_ratio_tol=0.09, # Default tolerance\n", + " max_angle_tol=0.03, # Default tolerance\n", + " max_length_tol=0.03 # Default tolerance\n", ")\n", "\n", - "interfaces_12_sorted = matched_interfaces_builder_12.get_materials(configuration=interface_configuration_12)" + "# Get ZSL matches for the second interface\n", + "matches_12 = zsl_analyzer_12.zsl_match_holders" ], - "metadata": { - "collapsed": false - }, - "id": "6f30c6961f7abbfe", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.6. Plot and Select Second Interface\n" - ], + "id": "32ded9bdae6ef429", "metadata": { "collapsed": false }, - "id": "32ded9bdae6ef429" + "source": [ + "### 3.6. Plot and Select Second Interface\n" + ] }, { "cell_type": "code", - "outputs": [], - "source": [ - "plot_strain_vs_atoms(interfaces_12_sorted, PLOT_SETTINGS)\n", - "\n", - "# Select the first interface with the lowest strain and smallest number of atoms\n", - "interfaces_slice_range_12 = slice(0, 1)\n", - "selected_interfaces_12 = interfaces_12_sorted[interfaces_slice_range_12]" - ], + "id": "43f233403393eb2a", "metadata": { "collapsed": false }, - "id": "43f233403393eb2a", + "source": [ + "plot_strain_vs_area(matches_12, PLOT_SETTINGS)\n", + "\n", + "# Select the interface with the lowest strain and smallest number of atoms\n", + "selected_index_12 = 0\n", + "\n", + "# Create the second interface using the newer approach\n", + "interface_12 = create_zsl_interface_between_slabs(\n", + " substrate_slab=substrate_second,\n", + " film_slab=material2_slab,\n", + " gap=INTERFACE_12_DISTANCE,\n", + " vacuum=FINAL_INTERFACE_VACUUM,\n", + " match_id=selected_index_12,\n", + " max_area=MAX_AREA_12,\n", + ")\n", + "\n", + "selected_interfaces_12 = [interface_12]" + ], + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.7. Preview the Second Interface (Final Heterostructure)\n" - ], + "id": "ed109941d5e29522", "metadata": { "collapsed": false }, - "id": "ed109941d5e29522" + "source": [ + "### 3.7. Preview the Second Interface (Final Heterostructure)\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "fffbf9243911a98", + "metadata": { + "collapsed": false + }, "source": [ "visualize(selected_interfaces_12, repetitions=[3, 3, 1])\n", "visualize(selected_interfaces_12, repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "fffbf9243911a98", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 4. Preview the Final Heterostructure\n" - ], + "id": "e98176e806c4aace", "metadata": { "collapsed": false }, - "id": "e98176e806c4aace" + "source": [ + "## 4. Preview the Final Heterostructure\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "47f9a1aa1578c37", + "metadata": { + "collapsed": false + }, "source": [ "visualize(selected_interfaces_12, repetitions=[3, 3, 1], title=\"Final Heterostructure (First Interface + Material2)\")\n", "visualize(selected_interfaces_12, repetitions=[3, 3, 1], rotation=\"-90x\", title=\"Final Heterostructure (First Interface + Material2) Rotated\")" ], - "metadata": { - "collapsed": false - }, - "id": "47f9a1aa1578c37", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", + "id": "946d5a41156bc1e1", + "metadata": { + "collapsed": false + }, "source": [ "## 5. Pass the Final Heterostructure to the Outside Runtime\n", "\n", "Pass the resulting heterostructure with an adjusted name to `set_materials()`.\n" - ], - "metadata": { - "collapsed": false - }, - "id": "946d5a41156bc1e1" + ] }, { "cell_type": "code", - "outputs": [], + "id": "1b466c32b0d82431", + "metadata": { + "collapsed": false + }, "source": [ "from utils.jupyterlite import set_materials\n", "\n", @@ -735,10 +784,7 @@ "\n", "set_materials(final_heterostructure)" ], - "metadata": { - "collapsed": false - }, - "id": "1b466c32b0d82431", + "outputs": [], "execution_count": null } ], 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 205d91354..13f2f833b 100644 --- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb +++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb @@ -45,39 +45,48 @@ } }, { + "metadata": {}, "cell_type": "code", "source": [ + "from mat3ra.made.tools.build.slab.configurations import SlabConfiguration\n", + "\n", "# Enable interactive selection of terminations via UI prompt\n", - "IS_TERMINATIONS_SELECTION_INTERACTIVE = False \n", + "IS_TERMINATIONS_SELECTION_INTERACTIVE = False\n", "\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_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_TERMINATION_FORMULA = None # if None, the first termination will be used\n", "FILM_VACUUM = 0.0 # in angstroms\n", "FILM_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "FILM_USE_ORTHOGONAL_Z = True\n", + "FILM_USE_ORTHOGONAL_C = True\n", "\n", "SUBSTRATE_INDEX = 0\n", - "SUBSTRATE_MILLER_INDICES = (0,0,1)\n", + "SUBSTRATE_MILLER_INDICES = (0, 0, 1)\n", "SUBSTRATE_THICKNESS = 3 # in atomic layers\n", + "SUBSTRATE_TERMINATION_FORMULA = None # if None, the first termination will be used\n", "SUBSTRATE_VACUUM = 0.0 # in angstroms\n", "SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "SUBSTRATE_USE_ORTHOGONAL_Z = True\n", + "SUBSTRATE_USE_ORTHOGONAL_C = True\n", + "\n", + "INTERFACE_DISTANCE = 3.0 # Gap between substrate and film, in Angstrom\n", + "INTERFACE_VACUUM = 10.0 # Vacuum over film, in Angstrom\n", "\n", - "# Maximum area for the superlattice search algorithm\n", - "MAX_AREA = 50 # in Angstrom^2\n", + "# Whether to convert materials to conventional cells before creating slabs.\n", + "# To create interfaces with smaller cells, set this flag to False. (and pass already conventional cells as input)\n", + "USE_CONVENTIONAL_CELL = True\n", + "\n", + "# Maximum area for the superlattice search algorithm (the final interface area will be smaller)\n", + "MAX_AREA = 150 # in Angstrom^2\n", "# Additional fine-tuning parameters (increase values to get more strained matches):\n", - "MAX_AREA_TOLERANCE = 0.09 # in Angstrom^2\n", - "MAX_ANGLE_TOLERANCE = 0.03\n", - "MAX_LENGTH_TOLERANCE = 0.03\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", - "INTERFACE_VACUUM = 20.0 # in Angstrom" + "MAX_AREA_TOLERANCE = 0.09 # in Angstrom^2\n", + "MAX_LENGTH_TOLERANCE = 0.05\n", + "MAX_ANGLE_TOLERANCE = 0.02\n", + "\n", + "# Whether to reduce the resulting interface cell to the primitive cell after the interface creation.\n", + "# If the reduction causes unexpected results, try increasing the `MAX_AREA` for search.\n", + "REDUCE_RESULT_CELL_TO_PRIMITIVE = True" ], - "metadata": { - "collapsed": false - }, "outputs": [], "execution_count": null }, @@ -98,10 +107,11 @@ "\n", "if sys.platform == \"emscripten\":\n", " import micropip\n", - " \n", + "\n", " await micropip.install('mat3ra-api-examples', deps=False)\n", " await micropip.install('mat3ra-utils')\n", " from mat3ra.utils.jupyterlite.packages import install_packages\n", + "\n", " await install_packages(\"create_interface_with_min_strain_zsl.ipynb\")" ], "metadata": { @@ -125,7 +135,7 @@ "\n", "materials = get_materials(globals())\n", "substrate = materials[SUBSTRATE_INDEX]\n", - "try: \n", + "try:\n", " film = materials[FILM_INDEX]\n", "except IndexError:\n", " print(\"Film material not found. Re-using substrate material as film.\")\n", @@ -150,6 +160,7 @@ "cell_type": "code", "source": [ "from utils.visualize import visualize_materials as visualize\n", + "\n", "visualize([substrate, film], repetitions=[3, 3, 1], rotation=\"0x\")" ], "metadata": { @@ -159,198 +170,143 @@ "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "## 2. Configure slabs and select termination pair\n", - "\n", - "### 2.1. Create Substrate and Layer Slabs\n", - "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations.\n", - "Define the substrate slab cell that will be used as a base for the interface and the film slab cell that will be placed on top of the substrate slab." - ], - "metadata": {} + "source": "## 2. Configure slabs for interface\n" }, { - "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n", - "\n", - "film_slab_configuration = SlabConfiguration(\n", - " bulk=film,\n", - " miller_indices=FILM_MILLER_INDICES,\n", - " number_of_layers=FILM_THICKNESS, # 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", - "\n", - "substrate_slab_configuration = SlabConfiguration(\n", - " bulk=substrate,\n", - " miller_indices=SUBSTRATE_MILLER_INDICES,\n", - " number_of_layers=SUBSTRATE_THICKNESS, # 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", - ")" - ], "metadata": {}, - "outputs": [], - "execution_count": null - }, - { "cell_type": "markdown", - "source": [ - "### 2.2. Get possible terminations for the slabs" - ], - "metadata": { - "collapsed": false - } + "source": "### 2.1. Get possible terminations for the slabs" }, { - "cell_type": "code", - "source": [ - "film_slab_terminations = get_terminations(film_slab_configuration)\n", - "substrate_slab_terminations = get_terminations(substrate_slab_configuration)" - ], "metadata": { "collapsed": false }, - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.3. Visualize slabs for all possible terminations" - ], - "metadata": { - "collapsed": false - } - }, - { "cell_type": "code", "source": [ - "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", + "from mat3ra.made.tools.build.slab.helpers import get_slab_terminations\n", "\n", - "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\") " + "film_slab_terminations = get_slab_terminations(material=film, miller_indices=FILM_MILLER_INDICES)\n", + "substrate_slab_terminations = get_slab_terminations(material=substrate, miller_indices=SUBSTRATE_MILLER_INDICES)\n", + "print(\"Film slab terminations:\", film_slab_terminations)\n", + "print(\"Substrate slab terminations:\", substrate_slab_terminations)" ], - "metadata": { - "collapsed": false - }, "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.4. Print terminations for the interface" - ], - "metadata": { - "collapsed": false - } + "source": "### 2.2. Visualize slabs for all possible terminations" }, { + "metadata": { + "collapsed": false + }, "cell_type": "code", "source": [ - "from itertools import product\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", + "from mat3ra.made.tools.build.interface.helpers import create_zsl_interface_between_slabs\n", + "from mat3ra.made.tools.build.slab.termination_utils import select_slab_termination\n", + "\n", + "film_slabs = [create_slab(film, miller_indices=FILM_MILLER_INDICES, termination=termination, vacuum=0) for termination\n", + " in\n", + " film_slab_terminations]\n", + "\n", + "substrate_slabs = [create_slab(substrate, miller_indices=SUBSTRATE_MILLER_INDICES, termination=termination, vacuum=0)\n", + " for termination in\n", + " substrate_slab_terminations]\n", "\n", - "termination_pairs = list(product(film_slab_terminations, substrate_slab_terminations)) \n", - "print(\"Termination Pairs (Film, Substrate)\")\n", - "for idx, termination_pair in enumerate(termination_pairs):\n", - " print(f\" {idx}: {termination_pair}\")" + "film_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in\n", + " zip(film_slabs, film_slab_terminations)]\n", + "substrate_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in\n", + " zip(substrate_slabs, substrate_slab_terminations)]\n", + "\n", + "visualize(film_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")\n", + "visualize(substrate_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.5. Select termination pair for the interface" - ], - "metadata": { - "collapsed": false - } + "source": "### 2.3. Select terminations for the Slabs" }, { + "metadata": {}, "cell_type": "code", "source": [ - "from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n", - "\n", - "termination_pair_index = TERMINATION_PAIR_INDEX\n", - "\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", - " else:\n", - " termination_pair = ui_prompt_select_array_element_by_index(termination_pairs, element_name=\"film/substrate termination pair\")" + "film_termination = select_slab_termination(film_slab_terminations, FILM_TERMINATION_FORMULA)\n", + "substrate_termination = select_slab_termination(substrate_slab_terminations, SUBSTRATE_TERMINATION_FORMULA)" ], - "metadata": { - "collapsed": false - }, "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "## 3. Create interfaces\n", - "\n", - "### 3.1. Initialize the Interface Configuration" - ], - "metadata": { - "collapsed": false - } + "### 2.4. Create Substrate and Layer Slabs\n", + "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations.\n", + "Define the substrate slab cell that will be used as a base for the interface and the film slab cell that will be placed on top of the substrate slab." + ] }, { + "metadata": {}, "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.interface import InterfaceConfiguration\n", - "\n", - "film_termination, substrate_termination = termination_pair\n", - "interface_configuration = InterfaceConfiguration(\n", - " film_configuration=film_slab_configuration,\n", - " substrate_configuration=substrate_slab_configuration,\n", - " film_termination=film_termination,\n", - " substrate_termination=substrate_termination,\n", - " distance_z=INTERFACE_DISTANCE,\n", - " vacuum= INTERFACE_VACUUM\n", - ")" + "from mat3ra.made.tools.build.slab.builders import SlabBuilder\n", + "\n", + "substrate_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=substrate,\n", + " miller_indices=SUBSTRATE_MILLER_INDICES,\n", + " number_of_layers=SUBSTRATE_THICKNESS,\n", + " vacuum=0.0,\n", + " termination_formula=SUBSTRATE_TERMINATION_FORMULA,\n", + " use_conventional_cell=USE_CONVENTIONAL_CELL\n", + ")\n", + "\n", + "film_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=film,\n", + " miller_indices=FILM_MILLER_INDICES,\n", + " number_of_layers=FILM_THICKNESS,\n", + " vacuum=0.0,\n", + " termination_formula=FILM_TERMINATION_FORMULA,\n", + " use_conventional_cell=USE_CONVENTIONAL_CELL\n", + ")\n", + "\n", + "substrate_slab = SlabBuilder().get_material(substrate_slab_config)\n", + "film_slab = SlabBuilder().get_material(film_slab_config)" ], - "metadata": { - "collapsed": false - }, "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "### 3.2. Set Strain Matching Algorithm Parameters (Optional)\n", + "### 3.2. Analyze possible interfaces with ZSL Analyzer\n", "The search algorithm for supercells matching can be tuned by setting its parameters directly, otherwise the default values are used." - ], - "metadata": { - "collapsed": false - } + ] }, { + "metadata": {}, "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.interface import ZSLStrainMatchingParameters\n", - "zsl_strain_matching_parameters = ZSLStrainMatchingParameters(\n", + "from mat3ra.made.tools.analyze.interface import ZSLInterfaceAnalyzer\n", + "\n", + "zsl_analyzer = ZSLInterfaceAnalyzer(\n", + " substrate_slab_configuration=substrate_slab_config,\n", + " film_slab_configuration=film_slab_config,\n", " max_area=MAX_AREA,\n", - " max_area_tol=MAX_AREA_TOLERANCE,\n", - " max_angle_tol=MAX_ANGLE_TOLERANCE,\n", + " max_area_ratio_tol=MAX_AREA_TOLERANCE,\n", " max_length_tol=MAX_LENGTH_TOLERANCE,\n", + " max_angle_tol=MAX_ANGLE_TOLERANCE,\n", + " reduce_result_cell=False # Reduces supercell matrices in analyzer\n", ")" ], - "metadata": { - "collapsed": false - }, "outputs": [], "execution_count": null }, @@ -365,17 +321,9 @@ } }, { + "metadata": {}, "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.interface import ZSLStrainMatchingInterfaceBuilder, ZSLStrainMatchingInterfaceBuilderParameters\n", - "\n", - "matched_interfaces_builder = ZSLStrainMatchingInterfaceBuilder(build_parameters=ZSLStrainMatchingInterfaceBuilderParameters(strain_matching_parameters=zsl_strain_matching_parameters))\n", - "\n", - "interfaces_sorted_by_size_and_strain= matched_interfaces_builder.get_materials(configuration=interface_configuration)" - ], - "metadata": { - "collapsed": false - }, + "source": "matches = zsl_analyzer.zsl_match_holders", "outputs": [], "execution_count": null }, @@ -391,7 +339,7 @@ { "cell_type": "code", "source": [ - "from utils.plot import plot_strain_vs_atoms\n", + "from utils.plot import plot_strain_vs_area\n", "\n", "PLOT_SETTINGS = {\n", " \"HEIGHT\": 600,\n", @@ -399,7 +347,7 @@ " \"Y_SCALE\": \"log\", # or linear\n", "}\n", "\n", - "plot_strain_vs_atoms(interfaces_sorted_by_size_and_strain, PLOT_SETTINGS)" + "plot_strain_vs_area(matches, PLOT_SETTINGS)" ], "metadata": { "collapsed": false @@ -408,26 +356,52 @@ "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ "### 3.5. Select the interface\n", "\n", "Select the index for the interface with the lowest strain and the smallest number of atoms." - ], + ] + }, + { "metadata": { "collapsed": false - } + }, + "cell_type": "code", + "source": "selected_index = 0", + "outputs": [], + "execution_count": null }, { - "cell_type": "code", + "metadata": {}, + "cell_type": "markdown", "source": [ - "# select the first interface with the lowest strain and the smallest number of atoms\n", - "interfaces_slice_range_or_index = slice(0, 1)\n", - "selected_interfaces = interfaces_sorted_by_size_and_strain[interfaces_slice_range_or_index]" - ], + "## 3. Create the interface\n", + "\n", + "### 3.1. Initialize the Interface Configuration" + ] + }, + { "metadata": { "collapsed": false }, + "cell_type": "code", + "source": [ + "\n", + "interface = create_zsl_interface_between_slabs(\n", + " substrate_slab=substrate_slab,\n", + " film_slab=film_slab,\n", + " gap=INTERFACE_DISTANCE,\n", + " vacuum=INTERFACE_VACUUM,\n", + " match_id=selected_index,\n", + " max_area=MAX_AREA,\n", + " max_area_ratio_tol=MAX_AREA_TOLERANCE,\n", + " max_length_tol=MAX_LENGTH_TOLERANCE,\n", + " max_angle_tol=MAX_ANGLE_TOLERANCE,\n", + " reduce_result_cell_to_primitive=REDUCE_RESULT_CELL_TO_PRIMITIVE,\n", + ")" + ], "outputs": [], "execution_count": null }, @@ -443,8 +417,8 @@ { "cell_type": "code", "source": [ - "visualize(selected_interfaces, repetitions=[3, 3, 1])\n", - "visualize(selected_interfaces, repetitions=[3, 3, 1], rotation=\"-90x\")" + "visualize(interface, repetitions=[1, 1, 1])\n", + "visualize(interface, repetitions=[1, 1, 1], rotation=\"-90x\")" ], "metadata": { "collapsed": false @@ -464,7 +438,8 @@ "metadata": {}, "source": [ "from utils.jupyterlite import set_materials\n", - "set_materials(selected_interfaces)" + "\n", + "set_materials(interface)" ], "outputs": [], "execution_count": null 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 0dde92501..5fd58e1e7 100644 --- a/other/materials_designer/create_interface_with_no_strain_matching.ipynb +++ b/other/materials_designer/create_interface_with_no_strain_matching.ipynb @@ -37,13 +37,14 @@ } }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ "# 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\n", + "\n", "# Create slabs for the film and substrate when creating the interface, otherwise use provided materials directly.\n", "CREATE_SLABS = True \n", "\n", @@ -51,24 +52,26 @@ "FILM_MILLER_INDICES = (0, 0, 1)\n", "FILM_THICKNESS = 1 # in atomic layers\n", "FILM_VACUUM = 0.0 # in angstroms\n", + "FILM_TERMINATION_FORMULA = None # if None, the first termination will be used\n", "FILM_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "FILM_USE_ORTHOGONAL_Z = True\n", + "FILM_USE_ORTHOGONAL_C = True\n", + "FILM_XY_SHIFT = [0.0, 0.0] # in Angstroms, shift the film slab in the XY plane relative to the substrate slab\n", "\n", "SUBSTRATE_INDEX = 0\n", "SUBSTRATE_MILLER_INDICES = (1, 1, 1)\n", "SUBSTRATE_THICKNESS = 3 # in atomic layers\n", "SUBSTRATE_VACUUM = 3.0 # in angstroms\n", + "SUBSTRATE_TERMINATION_FORMULA = None # if None, the first termination will be used\n", "SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", - "SUBSTRATE_USE_ORTHOGONAL_Z = True\n", + "SUBSTRATE_USE_ORTHOGONAL_C = True\n", + "\n", + "# Whether to convert materials to conventional cells before creating slabs.\n", + "USE_CONVENTIONAL_CELL = False\n", "\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", "INTERFACE_VACUUM = 20.0 # in Angstrom" ], - "metadata": { - "collapsed": false - }, + "outputs": [], "execution_count": null }, { @@ -84,7 +87,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -98,6 +100,7 @@ "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { @@ -112,7 +115,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -127,6 +129,7 @@ "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { @@ -140,7 +143,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "visualize([substrate, film], repetitions=[3, 3, 1], rotation=\"0x\")" @@ -148,148 +150,124 @@ "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "## 2. Configure slabs and select termination pair\n", - "\n", - "### 2.1. Create Substrate and Layer Slabs\n", - "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations.\n", - "Define the substrate slab cell that will be used as a base for the interface and the film slab cell that will be placed on top of the substrate slab." - ], - "metadata": { - "collapsed": false - } + "## 2. Create slabs for the interface\n", + "\n" + ] + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### 2.2. Get possible terminations for the slabs" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n", - "\n", - "film_slab_configuration = SlabConfiguration(\n", - " bulk=film,\n", - " miller_indices=FILM_MILLER_INDICES,\n", - " number_of_layers=FILM_THICKNESS, # 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", + "from mat3ra.made.tools.build.slab.helpers import get_slab_terminations\n", "\n", - "substrate_slab_configuration = SlabConfiguration(\n", - " bulk=substrate,\n", - " miller_indices=SUBSTRATE_MILLER_INDICES,\n", - " number_of_layers=SUBSTRATE_THICKNESS, # 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", - ")" + "film_slab_terminations = get_slab_terminations(film, miller_indices=FILM_MILLER_INDICES)\n", + "substrate_slab_terminations = get_slab_terminations(substrate, miller_indices=SUBSTRATE_MILLER_INDICES)" ], - "metadata": { - "collapsed": false - }, + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.2. Get possible terminations for the slabs" - ], - "metadata": { - "collapsed": false - } + "source": "### 2.3. Visualize slabs for all possible terminations" }, { - "cell_type": "code", - "outputs": [], - "source": [ - "film_slab_terminations = get_terminations(film_slab_configuration)\n", - "substrate_slab_terminations = get_terminations(substrate_slab_configuration)" - ], "metadata": { "collapsed": false }, - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.3. Visualize slabs for all possible terminations" - ], - "metadata": { - "collapsed": false - } - }, - { "cell_type": "code", - "outputs": [], "source": [ - "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", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", + "from mat3ra.made.tools.build.slab.termination_utils import select_slab_termination\n", "\n", - "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\") " + "film_slabs = [create_slab(film, miller_indices=FILM_MILLER_INDICES, termination=termination, vacuum=0) for termination\n", + " in\n", + " film_slab_terminations]\n", + "\n", + "substrate_slabs = [create_slab(substrate, miller_indices=SUBSTRATE_MILLER_INDICES, termination=termination, vacuum=0)\n", + " for termination in\n", + " substrate_slab_terminations]\n", + "\n", + "film_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in\n", + " zip(film_slabs, film_slab_terminations)]\n", + "substrate_slabs_with_titles = [{\"material\": slab, \"title\": str(termination)} for slab, termination in\n", + " zip(substrate_slabs, substrate_slab_terminations)]\n", + "\n", + "visualize(film_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")\n", + "visualize(substrate_slabs_with_titles, repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.4. Print terminations for the interface" - ], - "metadata": { - "collapsed": false - } + "source": "### 2.3. Select terminations for the Slabs" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ - "from itertools import product\n", - "\n", - "termination_pairs = list(product(film_slab_terminations, substrate_slab_terminations)) \n", - "print(\"Termination Pairs (Film, Substrate)\")\n", - "for idx, termination_pair in enumerate(termination_pairs):\n", - " print(f\" {idx}: {termination_pair}\")\n", - " " + "film_termination = select_slab_termination(film_slab_terminations, FILM_TERMINATION_FORMULA)\n", + "substrate_termination = select_slab_termination(substrate_slab_terminations, SUBSTRATE_TERMINATION_FORMULA)" ], - "metadata": { - "collapsed": false - }, + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "### 2.5. Select termination pair for the interface" - ], - "metadata": { - "collapsed": false - } + "### 2.1. Create Substrate and Layer Slabs\n", + "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations.\n", + "Define the substrate slab cell that will be used as a base for the interface and the film slab cell that will be placed on top of the substrate slab." + ] }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ - "from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", "\n", - "termination_pair_index = TERMINATION_PAIR_INDEX\n", + "if CREATE_SLABS:\n", + " film_slab = create_slab(\n", + " crystal=film,\n", + " miller_indices=FILM_MILLER_INDICES,\n", + " termination=film_termination,\n", + " number_of_layers=FILM_THICKNESS, # in atomic layers\n", + " vacuum=FILM_VACUUM, # in angstroms\n", + " xy_supercell_matrix=FILM_XY_SUPERCELL_MATRIX,\n", + " use_orthogonal_c=FILM_USE_ORTHOGONAL_C,\n", + " use_conventional_cell=USE_CONVENTIONAL_CELL\n", + " )\n", "\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", - " else:\n", - " termination_pair = ui_prompt_select_array_element_by_index(termination_pairs, element_name=\"film/substrate termination pair\")" + " substrate_slab = create_slab(\n", + " crystal=substrate,\n", + " miller_indices=SUBSTRATE_MILLER_INDICES,\n", + " termination=substrate_termination,\n", + " number_of_layers=SUBSTRATE_THICKNESS, # in atomic layers\n", + " vacuum=SUBSTRATE_VACUUM, # in angstroms\n", + " xy_supercell_matrix=SUBSTRATE_XY_SUPERCELL_MATRIX,\n", + " use_orthogonal_c=SUBSTRATE_USE_ORTHOGONAL_C,\n", + " use_conventional_cell=USE_CONVENTIONAL_CELL\n", + " )\n", + "else:\n", + " film_slab = film\n", + " substrate_slab = substrate\n" ], - "metadata": { - "collapsed": false - }, + "outputs": [], "execution_count": null }, { @@ -297,71 +275,35 @@ "metadata": {}, "source": [ "## 3. Create an interface\n", - "### 3.1. Initialize the Interface Configuration\n", + "### 3.1. Create an interface with no strain matching\n", "We use no strain matching for the interface construction. Substrate slab cell is used as a base and the film slab is placed on top of it with the specified distance." ] }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], + "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.interface import InterfaceConfiguration, create_interface\n", + "from mat3ra.made.tools.build.interface.helpers import create_simple_interface_between_slabs\n", "\n", - "film_termination, substrate_termination = termination_pair\n", - "interface_configuration = InterfaceConfiguration(\n", - " film_configuration=film_slab_configuration,\n", - " substrate_configuration=substrate_slab_configuration,\n", - " film_termination=film_termination,\n", - " substrate_termination=substrate_termination,\n", - " interface_distance=INTERFACE_DISTANCE, # in Angstrom\n", - " interface_vacuum=INTERFACE_VACUUM # in Angstrom\n", + "interface = create_simple_interface_between_slabs(\n", + " film_slab=film_slab,\n", + " substrate_slab=substrate_slab,\n", + " gap =INTERFACE_DISTANCE,\n", + " vacuum=INTERFACE_VACUUM,\n", + " xy_shift=FILM_XY_SHIFT\n", ")" - ] - }, - { - "cell_type": "markdown", - "source": [ - "### 3.2. Scale the film slab to match the substrate lattice (optional)" ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "from mat3ra.made.tools.build.interface import SimpleInterfaceBuilder, SimpleInterfaceBuilderParameters\n", - "\n", - "builder = SimpleInterfaceBuilder(build_parameters=SimpleInterfaceBuilderParameters(scale_film=ENABLE_FILM_SCALING, create_slabs=CREATE_SLABS))\n", - "interface = builder.get_material(configuration=interface_configuration)" - ], - "metadata": { - "collapsed": false - }, "execution_count": null }, { - "cell_type": "markdown", - "source": [ - "## 4. Preview the selected material" - ], - "metadata": { - "collapsed": false - } - }, - { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ "visualize([interface], repetitions=[3, 3, 1])\n", "visualize([interface], repetitions=[3, 3, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, + "outputs": [], "execution_count": null }, { @@ -373,13 +315,13 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "set_materials(interface)" - ] + ], + "outputs": [], + "execution_count": null } ], "metadata": { 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 a700eb7e6..9986ddcff 100644 --- a/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb +++ b/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb @@ -40,15 +40,15 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "MATERIAL_INDEX = 0 # Index of the material in the list of materials\n", + "MATERIAL_INDEX = 0 # Index of the material in the list of materials, should be an interface\n", "# Maximum force tolerance for the relaxation to stop, in eV/Å\n", "FMAX = 0.05" ], "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { @@ -63,7 +63,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -77,6 +76,7 @@ "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { @@ -91,15 +91,15 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", "materials = get_materials(globals())\n", "interface = materials[MATERIAL_INDEX]" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -112,13 +112,13 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "visualize(interface, repetitions=[3, 3, 1], rotation=\"0x\")" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -132,7 +132,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from ase.optimize import BFGS\n", "from ase.calculators.emt import EMT\n", @@ -147,6 +146,7 @@ "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { @@ -160,7 +160,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from mat3ra.utils.jupyterlite.plot import create_realtime_plot, create_update_callback\n", "from mat3ra.made.tools.convert import from_ase\n", @@ -197,11 +196,12 @@ "dyn.run(fmax=OPTIMIZATION_PARAMETERS[\"FMAX\"])\n", "\n", "ase_final_interface = ase_interface\n", - "final_interface = Material(from_ase(ase_final_interface))" + "final_interface = Material.create(from_ase(ase_final_interface))" ], "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null }, { @@ -213,12 +213,12 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "visualize([{\"material\": interface, \"title\": \"original\"}, {\"material\":final_interface, \"title\":\"relaxed\"}], rotation= \"-90x\", repetitions=[3, 3, 1])\n" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -230,9 +230,7 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "from mat3ra.made.tools.calculate import calculate_total_energy, calculate_interfacial_energy\n", "\n", @@ -244,7 +242,9 @@ "print(f\"Starting interface energy: {original_energy:.4f} eV\")\n", "print(f\"Relaxed interface energy: {relaxed_energy:.4f} eV\")\n", "print(f\"Interfacial energy: {interfacial_energy:.4f} eV\")" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -257,7 +257,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "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", @@ -266,6 +265,7 @@ "metadata": { "collapsed": false }, + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_island_defect.ipynb b/other/materials_designer/create_island_defect.ipynb index 2af826181..8d6ee4376 100644 --- a/other/materials_designer/create_island_defect.ipynb +++ b/other/materials_designer/create_island_defect.ipynb @@ -39,6 +39,7 @@ { "cell_type": "code", "source": [ + "\n", "# Shape-specific parameters\n", "# Choose the island shape: 'cylinder', 'sphere', 'box', or 'triangular_prism'\n", "# and the corresponding parameters\n", @@ -52,7 +53,7 @@ "# Common parameters\n", "CENTER_POSITION = [0.5, 0.5, 0.5] # Center of the island\n", "USE_CARTESIAN_COORDINATES = False # Use Cartesian coordinates for the island\n", - "NUMBER_OF_ADDED_LAYERS = 1 # Number of layers to add to the island\n", + "NUMBER_OF_ADDED_LAYERS = 3 # Number of layers to add to the island\n", "\n", "# Vacuum parameters for builder\n", "AUTO_ADD_VACUUM = True # Automatically add vacuum to the slab\n", @@ -63,7 +64,7 @@ " \"miller_indices\": (0,0,1),\n", " \"thickness\": 3,\n", " \"vacuum\": 5.0,\n", - " \"use_orthogonal_z\": True,\n", + " \"use_orthogonal_c\": True,\n", " \"xy_supercell_matrix\": [[3, 0], [0, 3]]\n", "}\n", "\n", @@ -163,22 +164,22 @@ { "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", "from utils.visualize import visualize_materials as visualize\n", "\n", "slab = materials[0]\n", - "if not slab.metadata or slab.metadata[\"build\"][\"configuration\"][\"type\"] != SlabConfiguration.__name__:\n", + "\n", + "if not slab.metadata or not slab.metadata.build:\n", " print(\"The material is not a slab. Creating a new slab...\")\n", - " slab_config = SlabConfiguration(\n", - " bulk=materials[0],\n", + " slab = create_slab(\n", + " crystal=slab,\n", " miller_indices=DEFAULT_SLAB_PARAMETERS[\"miller_indices\"],\n", " number_of_layers=DEFAULT_SLAB_PARAMETERS[\"thickness\"],\n", " vacuum= DEFAULT_SLAB_PARAMETERS[\"vacuum\"],\n", - " use_orthogonal_z=DEFAULT_SLAB_PARAMETERS[\"use_orthogonal_z\"],\n", + " use_orthogonal_c=DEFAULT_SLAB_PARAMETERS[\"use_orthogonal_c\"],\n", " xy_supercell_matrix=DEFAULT_SLAB_PARAMETERS[\"xy_supercell_matrix\"]\n", " )\n", - " \n", - " slab = create_slab(slab_config)\n", + "\n", "\n", "visualize([{\"material\": slab, \"title\": \"Original material\"}])\n", "visualize([{\"material\": slab, \"title\": \"Original material\"}], rotation=\"-90x\")" @@ -194,7 +195,7 @@ "cell_type": "markdown", "source": [ "## 2. Create the Target Material\n", - "### 2.1. Initialize the defect configuration and builder" + "### 2.1. Initialize the defect conditions" ], "metadata": { "collapsed": false @@ -204,21 +205,12 @@ { "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.defect import IslandSlabDefectConfiguration\n", + "from mat3ra.made.tools.utils.coordinate import CylinderCoordinateCondition\n", "\n", - "\n", - "island_config = IslandSlabDefectConfiguration.from_dict(\n", - " crystal=slab,\n", - " condition=SHAPE_PARAMETERS,\n", - " number_of_added_layers = NUMBER_OF_ADDED_LAYERS\n", - ")\n", - "\n", - "from mat3ra.made.tools.build.defect import IslandSlabDefectBuilder, SlabDefectBuilderParameters\n", - "params = SlabDefectBuilderParameters(\n", - " auto_add_vacuum=AUTO_ADD_VACUUM,\n", - " vacuum_thickness=VACUUM_THICKNESS,\n", - ")\n", - "builder = IslandSlabDefectBuilder(build_parameters=params)" + "condition = CylinderCoordinateCondition(\n", + " center_position=CENTER_POSITION,\n", + " radius=SHAPE_PARAMETERS['radius'],\n", + ")" ], "metadata": { "collapsed": false @@ -240,7 +232,14 @@ { "cell_type": "code", "source": [ - "slab_with_island = builder.get_material(island_config)" + "from mat3ra.made.tools.build.defect.island.helpers import create_island_defect\n", + "\n", + "slab_with_island = create_island_defect(\n", + " slab=slab,\n", + " condition=condition,\n", + " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES,\n", + " number_of_added_layers=NUMBER_OF_ADDED_LAYERS,\n", + ")\n" ], "metadata": { "collapsed": false diff --git a/other/materials_designer/create_island_defect_custom.ipynb b/other/materials_designer/create_island_defect_custom.ipynb index 5cb4f3e03..3328fbbcb 100644 --- a/other/materials_designer/create_island_defect_custom.ipynb +++ b/other/materials_designer/create_island_defect_custom.ipynb @@ -40,11 +40,11 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "from typing import List\n", "\n", + "\n", "if sys.platform == \"emscripten\":\n", " import micropip\n", " await micropip.install('mat3ra-api-examples', deps=False)\n", @@ -56,6 +56,7 @@ "collapsed": false }, "id": "b1216c665d6cf493", + "outputs": [], "execution_count": null }, { @@ -69,15 +70,15 @@ "id": "c360bd0ea9a5f262" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ "import numpy as np\n", "from mat3ra.made.tools.utils.coordinate import CoordinateCondition\n", "\n", "# Custom Coordinate Condition for a torus shape\n", "class CustomCoordinateCondition(CoordinateCondition):\n", - " center: List[float] = [0.5, 0.5, 0.5]\n", + " center: List[float] = [0.5, 0.5, 0.0]\n", " major_radius: float = 0.5\n", " minor_radius: float = 0.1 \n", "\n", @@ -89,10 +90,8 @@ " distance_to_torus = np.sqrt((xy_distance - self.major_radius) ** 2 + (coord[2] - self.center[2]) ** 2)\n", " return distance_to_torus <= self.minor_radius\n" ], - "metadata": { - "collapsed": false - }, - "id": "9d8b1890b34d850a", + "id": "55f4289a6545c504", + "outputs": [], "execution_count": null }, { @@ -106,31 +105,28 @@ "id": "535bbac2c3f2832b" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ "CENTER_POSITION = [0.5, 0.5, 0.5] # Center of the torus in crystal coordinates\n", "MAJOR_RADIUS = 0.3 # Major radius of the torus\n", "MINOR_RADIUS = 0.1 # Minor radius of the torus\n", + "USE_CARTESIAN_COORDINATES = False # Use Cartesian coordinates for the condition\n", "\n", "NUMBER_OF_ADDED_LAYERS = 3 # Number of layers to add to the defect\n", "\n", - "AUTO_ADD_VACUUM = True # Automatically add vacuum to the slab\n", - "VACUUM_THICKNESS = 5.0 # Thickness of the vacuum to add\n", "\n", "# Create slab with default parameters if imported material is not a slab\n", "DEFAULT_SLAB_PARAMETERS = {\n", " \"miller_indices\": (0,0,1),\n", " \"thickness\": 3,\n", " \"vacuum\": 5.0,\n", - " \"use_orthogonal_z\": True,\n", + " \"use_orthogonal_c\": True,\n", " \"xy_supercell_matrix\": [[10, 0], [0, 10]]\n", "}" ], - "metadata": { - "collapsed": false - }, - "id": "79924b8b23c8850b", + "id": "4f6c437b81325730", + "outputs": [], "execution_count": null }, { @@ -145,7 +141,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "coordinate_condition = CustomCoordinateCondition(\n", " center=CENTER_POSITION,\n", @@ -157,6 +152,7 @@ "collapsed": false }, "id": "87c3850f6c7178b2", + "outputs": [], "execution_count": null }, { @@ -171,7 +167,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "materials = get_materials(globals())" @@ -180,6 +175,7 @@ "collapsed": false }, "id": "be38fdda1984c654", + "outputs": [], "execution_count": null }, { @@ -194,25 +190,22 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", "from utils.visualize import visualize_materials as visualize\n", "\n", "slab = materials[0]\n", - "if not slab.metadata or slab.metadata[\"build\"][\"configuration\"][\"type\"] != SlabConfiguration.__name__:\n", + "if not slab.metadata or not slab.metadata.build:\n", " print(\"The material is not a slab. Creating a new slab...\")\n", - " slab_config = SlabConfiguration(\n", - " bulk=materials[0],\n", + " slab = create_slab(\n", + " crystal=materials[0],\n", " miller_indices=DEFAULT_SLAB_PARAMETERS[\"miller_indices\"],\n", " number_of_layers=DEFAULT_SLAB_PARAMETERS[\"thickness\"],\n", " vacuum= DEFAULT_SLAB_PARAMETERS[\"vacuum\"],\n", - " use_orthogonal_z=DEFAULT_SLAB_PARAMETERS[\"use_orthogonal_z\"],\n", + " use_orthogonal_c=DEFAULT_SLAB_PARAMETERS[\"use_orthogonal_c\"],\n", " xy_supercell_matrix=DEFAULT_SLAB_PARAMETERS[\"xy_supercell_matrix\"]\n", " )\n", " \n", - " slab = create_slab(slab_config)\n", - "\n", "visualize([{\"material\": slab, \"title\": \"Original material\"}])\n", "visualize([{\"material\": slab, \"title\": \"Original material\"}], rotation=\"-90x\")" ], @@ -220,14 +213,12 @@ "collapsed": false }, "id": "7fcb1e02e84c5f35", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 2. Create the Target Material\n", - "### 2.1. Initialize the defect configuration and builder" - ], + "source": "## 2. Create the Target Material", "metadata": { "collapsed": false }, @@ -235,50 +226,21 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.defect import IslandSlabDefectConfiguration\n", - "from mat3ra.made.tools.build.defect import IslandSlabDefectBuilder, SlabDefectBuilderParameters\n", + "from mat3ra.made.tools.build.defect.island.helpers import create_island_defect\n", "\n", - "island_config = IslandSlabDefectConfiguration(\n", - " crystal=slab,\n", + "slab_with_island = create_island_defect(\n", + " slab=slab,\n", " condition=coordinate_condition,\n", - " number_of_added_layers=NUMBER_OF_ADDED_LAYERS\n", - ")\n", - "\n", - "\n", - "params = SlabDefectBuilderParameters(\n", - " auto_add_vacuum=AUTO_ADD_VACUUM,\n", - " vacuum_thickness=VACUUM_THICKNESS,\n", - ")\n", - "builder = IslandSlabDefectBuilder(build_parameters=params)" + " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES,\n", + " number_of_added_layers=NUMBER_OF_ADDED_LAYERS,\n", + ")" ], "metadata": { "collapsed": false }, "id": "e2d24109d3068c9e", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Create the island" - ], - "metadata": { - "collapsed": false - }, - "id": "489b51f0ee122c48" - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "slab_with_island = builder.get_material(island_config)" - ], - "metadata": { - "collapsed": false - }, - "id": "a990fa35742d7269", "execution_count": null }, { @@ -293,7 +255,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "visualize([{\"material\": slab, \"title\": \"Original material\"},\n", " {\"material\": slab_with_island, \"title\": f\"Material with Island Defect\"}],\n", @@ -306,6 +267,7 @@ "collapsed": false }, "id": "509b18661a069e42", + "outputs": [], "execution_count": null }, { @@ -320,7 +282,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", @@ -330,6 +291,7 @@ "collapsed": false }, "id": "61daa5afcbc078a9", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_monolayer.ipynb b/other/materials_designer/create_monolayer.ipynb index 4c4501e94..04bb3de53 100644 --- a/other/materials_designer/create_monolayer.ipynb +++ b/other/materials_designer/create_monolayer.ipynb @@ -32,7 +32,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "XY_SUPERCELL_MATRIX = [\n", " [3, 0],\n", @@ -45,6 +44,7 @@ "collapsed": false }, "id": "a2c8922a4e627887", + "outputs": [], "execution_count": null }, { @@ -60,7 +60,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -77,6 +76,7 @@ "collapsed": false }, "id": "b0c332f1c1f451fd", + "outputs": [], "execution_count": null }, { @@ -91,7 +91,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -102,6 +101,7 @@ "collapsed": false }, "id": "74cd0d5a3881ab47", + "outputs": [], "execution_count": null }, { @@ -116,7 +116,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "\n", @@ -127,6 +126,7 @@ "collapsed": false }, "id": "d6bea39864c23ab5", + "outputs": [], "execution_count": null }, { @@ -141,86 +141,62 @@ }, { "cell_type": "markdown", - "source": [ - "### 2.1. Create slab configuration\n", - "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations.\n" - ], + "source": "### 2.1. Create a monolayer unit cell", "metadata": { "collapsed": false }, "id": "ee17958872d03410" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.slab import SlabConfiguration\n", + "from mat3ra.made.tools.build.monolayer.helpers import create_monolayer\n", "\n", - "slab_configuration = number_of_layers=1,\n", + "monolayer = create_monolayer(\n", + " crystal=material,\n", " vacuum=VACUUM,\n", - " xy_supercell_matrix=XY_SUPERCELL_MATRIX,\n", - " use_orthogonal_z=True,\n", - " use_conventional_cell=True,\n", ")" ], - "metadata": { - "collapsed": false - }, - "id": "b8dc56881543c16c", + "id": "f05c4872edfef910", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.2 Create the slab of Single Layer" - ], - "metadata": { - "collapsed": false - }, - "id": "661c76f9bab9f743" + "source": "### 2.2 Create a supercell", + "id": "372400a5610d7247" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.modify import translate_to_z_level, filter_by_box\n", - "from mat3ra.made.tools.build.slab import create_slab\n", - "\n", - "slab = create_slab(slab_configuration)\n", + "from mat3ra.made.tools.operations.core.unary import supercell\n", "\n", - "# Get only the top layer of two -- for AB stacked bilayers forming a 3D bulk basis\n", - "if any(substring in material.name for substring in [\"3D\", \"Bulk\"]):\n", - " centered_slab = translate_to_z_level(slab, z_level=\"center\")\n", - " half_filtered_slab = filter_by_box(centered_slab, [0, 0, 0.5], [1, 1, 1])\n", - " monolayer = translate_to_z_level(half_filtered_slab, z_level=\"center\")" + "monolayer = supercell(\n", + " material=monolayer,\n", + " supercell_matrix=XY_SUPERCELL_MATRIX, )" ], - "metadata": { - "collapsed": false - }, - "id": "cf27e53c85adc447", + "id": "25d6681d5c1bfb0", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "## 3. Visualize the result" - ], - "metadata": { - "collapsed": false - }, - "id": "527829d64a542d10" + "source": "## 3. Visualize the result", + "id": "82f9dfac4c711634" }, { + "metadata": {}, "cell_type": "code", - "outputs": [], "source": [ "visualize(monolayer, repetitions=[1, 1, 1], rotation=\"0x\")\n", "visualize(monolayer, repetitions=[1, 1, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "ee12ab13c210b953", + "id": "ab5c2f5ee249525c", + "outputs": [], "execution_count": null }, { @@ -235,7 +211,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", @@ -245,6 +220,7 @@ "collapsed": false }, "id": "865c71d008d87beb", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_nanoribbon.ipynb b/other/materials_designer/create_nanoribbon.ipynb index 2be2be5ce..9a77e5a0f 100644 --- a/other/materials_designer/create_nanoribbon.ipynb +++ b/other/materials_designer/create_nanoribbon.ipynb @@ -41,19 +41,19 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "# Widths and lengths are in number of unit cells\n", - "WIDTH = 3\n", - "VACUUM_WIDTH = 2\n", - "LENGTH = 10\n", - "VACUUM_LENGTH = 0\n", + "WIDTH = 4 # in unit cells\n", + "LENGTH = 10 # in unit cells\n", + "VACUUM_WIDTH = 10.0 # in Angstroms\n", + "VACUUM_LENGTH = 10.0 # in Angstroms\n", "EDGE_TYPE = \"zigzag\" # \"zigzag\" or \"armchair\"" ], "metadata": { "collapsed": false }, "id": "a40d7b697c413113", + "outputs": [], "execution_count": null }, { @@ -69,7 +69,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -84,6 +83,7 @@ "collapsed": false }, "id": "c6d9f8e57bef2f91", + "outputs": [], "execution_count": null }, { @@ -99,7 +99,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "materials = get_materials(globals())" @@ -108,6 +107,7 @@ "collapsed": false }, "id": "e0c53233ce728cc1", + "outputs": [], "execution_count": null }, { @@ -122,25 +122,22 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "\n", - "material = materials[0]\n", + "material = materials[1]\n", "visualize(material, repetitions=[3, 3, 1], rotation=\"0x\")" ], "metadata": { "collapsed": false }, "id": "897ba7aa4e402d24", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 2. Create the Nanoribbon\n", - "### 2.1. Set nanoribbon parameters" - ], + "source": "## 2. Create the Nanoribbon\n", "metadata": { "collapsed": false }, @@ -148,48 +145,26 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.nanoribbon import NanoribbonBuilder, NanoribbonConfiguration\n", + "from mat3ra.made.tools.build.lattice_lines import EdgeTypes\n", + "from mat3ra.made.tools.build.nanoribbon.helpers import create_nanoribbon\n", + "\n", "\n", - "nanoribbon_configuration = NanoribbonConfiguration(\n", + "nanoribbon = create_nanoribbon(\n", " material=material,\n", " width=WIDTH,\n", - " vacuum_width=VACUUM_WIDTH,\n", " length=LENGTH,\n", + " vacuum_width=VACUUM_WIDTH,\n", " vacuum_length=VACUUM_LENGTH,\n", - " edge_type=EDGE_TYPE\n", - ")\n", - "\n", - "\n", - "builder = NanoribbonBuilder()" + " use_rectangular_lattice=True,\n", + " edge_type=EdgeTypes.zigzag if EDGE_TYPE == \"zigzag\" else EdgeTypes.armchair\n", + ")" ], "metadata": { "collapsed": false }, "id": "1991efeeebe39db4", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Create the Nanoribbon" - ], - "metadata": { - "collapsed": false - }, - "id": "d296d7287618dc0b" - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "nanoribbon = builder.get_material(nanoribbon_configuration)" - ], - "metadata": { - "collapsed": false - }, - "id": "302f417828a8fc9c", "execution_count": null }, { @@ -204,7 +179,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "visualize([{\"material\": nanoribbon, \"title\": \"Nanoribbon\"}])" @@ -213,6 +187,7 @@ "collapsed": false }, "id": "1ee393a7f2ec3bc8", + "outputs": [], "execution_count": null }, { @@ -227,7 +202,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "set_materials(nanoribbon)" @@ -236,6 +210,7 @@ "collapsed": false }, "id": "29dfa0a329cca2fa", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_nanowire.ipynb b/other/materials_designer/create_nanowire.ipynb index 0fa734e4e..454a75333 100644 --- a/other/materials_designer/create_nanowire.ipynb +++ b/other/materials_designer/create_nanowire.ipynb @@ -32,7 +32,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "MILLER_INDICES= (0,0,1) # Miller indices of the nanowire direction\n", "RADIUS = 5.0 # Wire radius in Angstroms\n", @@ -44,6 +43,7 @@ "collapsed": false }, "id": "2269749714d81b93", + "outputs": [], "execution_count": null }, { @@ -59,7 +59,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -75,6 +74,7 @@ "collapsed": false }, "id": "6dac92b719d539ec", + "outputs": [], "execution_count": null }, { @@ -89,7 +89,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -100,6 +99,7 @@ "collapsed": false }, "id": "b95701d7a0e593fe", + "outputs": [], "execution_count": null }, { @@ -114,7 +114,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "visualize(material, repetitions=[3,3,3], rotation=\"0x\")\n", @@ -124,6 +123,7 @@ "collapsed": false }, "id": "c98ec170f3ee6d24", + "outputs": [], "execution_count": null }, { @@ -139,22 +139,20 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import math\n", "from mat3ra.made.tools.build.supercell import create_supercell\n", "from mat3ra.made.tools.modify import filter_by_cylinder, add_vacuum_sides\n", - "from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", "\n", - "slab_config = SlabConfiguration(\n", - " bulk=material,\n", + "slab_unit_cell = create_slab(\n", + " crystal=material,\n", " miller_indices=MILLER_INDICES,\n", " number_of_layers=1,\n", " vacuum=0,\n", - " use_orthogonal_z=True,\n", + " use_orthogonal_c=True,\n", ")\n", "\n", - "slab_unit_cell = create_slab(slab_config)\n", "n_for_x = math.ceil(int(2*RADIUS / slab_unit_cell.lattice.a)) + 1\n", "n_for_y = math.ceil(int(2*RADIUS / slab_unit_cell.lattice.b)) + 1\n", "n_for_z = int(LENGTH / slab_unit_cell.lattice.c)\n", @@ -166,6 +164,7 @@ "collapsed": false }, "id": "c4b34b3287960dcc", + "outputs": [], "execution_count": null }, { @@ -180,7 +179,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "rotate_90_degree_matrix = [[0, 0, 1], [0, 1, 0], [-1, 0, 0]]\n", "nanowire_x = create_supercell(nanowire_z, supercell_matrix=rotate_90_degree_matrix)\n", @@ -190,6 +188,7 @@ "collapsed": false }, "id": "7401ab24726bf4e5", + "outputs": [], "execution_count": null }, { @@ -204,7 +203,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "visualize(nanowire, repetitions=[1, 1, 1], rotation=\"0x\")\n", "visualize(nanowire, repetitions=[1, 1, 1], rotation=\"-90x\")\n", @@ -214,6 +212,7 @@ "collapsed": false }, "id": "aea078560283ca95", + "outputs": [], "execution_count": null }, { @@ -228,7 +227,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "set_materials(nanowire)" @@ -237,6 +235,7 @@ "collapsed": false }, "id": "cdaf612bc6198546", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_nanowire_custom_shape.ipynb b/other/materials_designer/create_nanowire_custom_shape.ipynb index e70cd96de..ecd60a26b 100644 --- a/other/materials_designer/create_nanowire_custom_shape.ipynb +++ b/other/materials_designer/create_nanowire_custom_shape.ipynb @@ -42,7 +42,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -58,6 +57,7 @@ "collapsed": false }, "id": "bd0fdddfd8880b40", + "outputs": [], "execution_count": null }, { @@ -72,7 +72,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from typing import List\n", "\n", @@ -110,6 +109,7 @@ "collapsed": false }, "id": "e93f72e7c37dea10", + "outputs": [], "execution_count": null }, { @@ -124,7 +124,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -135,6 +134,7 @@ "collapsed": false }, "id": "4b72580121ca40d0", + "outputs": [], "execution_count": null }, { @@ -149,7 +149,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "visualize(material, repetitions=[3,3,3], rotation=\"0x\")\n", @@ -159,6 +158,7 @@ "collapsed": false }, "id": "d3cba46f185c1a1b", + "outputs": [], "execution_count": null }, { @@ -174,21 +174,19 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from mat3ra.made.tools.build.supercell import create_supercell\n", "from mat3ra.made.tools.modify import add_vacuum_sides, filter_by_condition_on_coordinates\n", - "from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", "\n", - "slab_config = SlabConfiguration(\n", - " bulk=material,\n", + "slab_unit_cell = create_slab(\n", + " crystal=material,\n", " miller_indices=MILLER_INDICES,\n", " number_of_layers=1,\n", " vacuum=0,\n", - " use_orthogonal_z=True,\n", + " use_orthogonal_c=True,\n", ")\n", "\n", - "slab_unit_cell = create_slab(slab_config)\n", "supercell = create_supercell(slab_unit_cell, supercell_matrix=SUPERCELL_MATRIX)\n", "nanowire_z = filter_by_condition_on_coordinates(supercell, condition=condition, use_cartesian_coordinates=USE_CARTESIAN_COORDINATES)\n", "nanowire_z = add_vacuum_sides(nanowire_z, vacuum=VACUUM, on_x=True, on_y=True) " @@ -197,6 +195,7 @@ "collapsed": false }, "id": "2795d5bdbbaafbe6", + "outputs": [], "execution_count": null }, { @@ -211,7 +210,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "rotate_90_degree_matrix = [[0, 0, 1], [0, 1, 0], [-1, 0, 0]]\n", "nanowire_x = create_supercell(nanowire_z, supercell_matrix=rotate_90_degree_matrix)\n", @@ -221,6 +219,7 @@ "collapsed": false }, "id": "87534e47ecdb9dc6", + "outputs": [], "execution_count": null }, { @@ -235,7 +234,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "visualize(nanowire, repetitions=[1, 1, 1], rotation=\"0x\")\n", "visualize(nanowire, repetitions=[1, 1, 1], rotation=\"-90x\")\n", @@ -245,6 +243,7 @@ "collapsed": false }, "id": "aea078560283ca95", + "outputs": [], "execution_count": null }, { @@ -259,7 +258,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "set_materials(nanowire)" @@ -268,6 +266,7 @@ "collapsed": false }, "id": "cdaf612bc6198546", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_perturbation.ipynb b/other/materials_designer/create_perturbation.ipynb index a3e28ecdf..309be3e24 100644 --- a/other/materials_designer/create_perturbation.ipynb +++ b/other/materials_designer/create_perturbation.ipynb @@ -37,13 +37,10 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "# Sine wave perturbation parameters\n", - "AMPLITUDE = 0.5\n", - "WAVELENGTH = 1.0\n", - "PHASE = 0.0\n", - "AXIS = \"y\"\n", + "# string representation of the perturbation function, function of x, y, z variables\n", + "\n", + "perturbation_function = \"0.5 * sin (2 * pi * x) \"\n", "\n", "USE_CARTESIAN_COORDINATES = False\n", "\n", @@ -55,6 +52,7 @@ "collapsed": false }, "id": "a40d7b697c413113", + "outputs": [], "execution_count": null }, { @@ -70,7 +68,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -87,6 +84,7 @@ "collapsed": false }, "id": "c6d9f8e57bef2f91", + "outputs": [], "execution_count": null }, { @@ -102,7 +100,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -112,6 +109,7 @@ "collapsed": false }, "id": "e0c53233ce728cc1", + "outputs": [], "execution_count": null }, { @@ -126,7 +124,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "from mat3ra.made.tools.build.supercell import create_supercell\n", @@ -139,6 +136,7 @@ "collapsed": false }, "id": "897ba7aa4e402d24", + "outputs": [], "execution_count": null }, { @@ -155,55 +153,21 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.perturbation import PerturbationConfiguration, SlabPerturbationBuilder, CellMatchingDistancePreservingSlabPerturbationBuilder\n", - "from mat3ra.made.tools.utils.perturbation import SineWavePerturbationFunctionHolder\n", - "\n", - "perturbation_function = SineWavePerturbationFunctionHolder(\n", - " amplitude=AMPLITUDE,\n", - " wavelength=WAVELENGTH,\n", - " phase=PHASE,\n", - " axis=AXIS)\n", + "from mat3ra.made.tools.build.perturbation.helpers import create_perturbation\n", "\n", - "configuration = PerturbationConfiguration(\n", + "material_with_perturbation = create_perturbation(\n", " material=supercell,\n", - " perturbation_function_holder=perturbation_function,\n", - " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES)\n", - "\n", - "if PRESERVE_GEODESIC_DISTANCE:\n", - " builder = CellMatchingDistancePreservingSlabPerturbationBuilder()\n", - "else:\n", - " builder = SlabPerturbationBuilder()" + " perturbation_function=perturbation_function,\n", + " is_isometric=PRESERVE_GEODESIC_DISTANCE,\n", + " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES\n", + ")\n" ], "metadata": { "collapsed": false }, "id": "1991efeeebe39db4", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Apply perturbation to the material" - ], - "metadata": { - "collapsed": false - }, - "id": "d296d7287618dc0b" - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "from mat3ra.made.tools.build.perturbation import create_perturbation\n", - "\n", - "material_with_perturbation = create_perturbation(configuration, builder)" - ], - "metadata": { - "collapsed": false - }, - "id": "d77821f7d0b8c330", "execution_count": null }, { @@ -218,7 +182,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "\n", @@ -231,6 +194,7 @@ "collapsed": false }, "id": "1ee393a7f2ec3bc8", + "outputs": [], "execution_count": null }, { @@ -245,7 +209,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", @@ -255,6 +218,7 @@ "collapsed": false }, "id": "29dfa0a329cca2fa", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_perturbation_custom.ipynb b/other/materials_designer/create_perturbation_custom.ipynb index 4d68aa538..460473dda 100644 --- a/other/materials_designer/create_perturbation_custom.ipynb +++ b/other/materials_designer/create_perturbation_custom.ipynb @@ -48,7 +48,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -65,6 +64,7 @@ "collapsed": false }, "id": "7a6e28cfae1a7b46", + "outputs": [], "execution_count": null }, { @@ -79,7 +79,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "# Set whether to preserve geodesic distance and scale the cell accordingly to match PBC\n", "PRESERVE_GEODESIC_DISTANCE = True\n", @@ -94,6 +93,7 @@ "collapsed": false }, "id": "a40d7b697c413113", + "outputs": [], "execution_count": null }, { @@ -109,7 +109,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sympy as sp\n", "\n", @@ -130,6 +129,7 @@ "collapsed": false }, "id": "203911c2413c7447", + "outputs": [], "execution_count": null }, { @@ -145,7 +145,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -155,6 +154,7 @@ "collapsed": false }, "id": "e0c53233ce728cc1", + "outputs": [], "execution_count": null }, { @@ -169,7 +169,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "from mat3ra.made.tools.build.supercell import create_supercell\n", @@ -182,6 +181,7 @@ "collapsed": false }, "id": "897ba7aa4e402d24", + "outputs": [], "execution_count": null }, { @@ -197,52 +197,22 @@ }, { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.perturbation import CellMatchingDistancePreservingSlabPerturbationBuilder, \\\n", - " PerturbationConfiguration, SlabPerturbationBuilder\n", - "from mat3ra.made.tools.utils.perturbation import PerturbationFunctionHolder\n", + "from mat3ra.made.tools.build.perturbation.helpers import create_perturbation\n", "\n", - "custom_perturbation_function = PerturbationFunctionHolder(function=custom_sympy_function,\n", - " variables=variable_names)\n", - "configuration_custom = PerturbationConfiguration(\n", - " material=supercell,\n", - " perturbation_function_holder=custom_perturbation_function,\n", - " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES)\n", "\n", - "if PRESERVE_GEODESIC_DISTANCE:\n", - " builder = CellMatchingDistancePreservingSlabPerturbationBuilder()\n", - "else:\n", - " builder = SlabPerturbationBuilder()" + "material_with_perturbation = create_perturbation(\n", + " material=supercell,\n", + " perturbation_function=custom_sympy_function,\n", + " is_isometric=PRESERVE_GEODESIC_DISTANCE,\n", + " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES\n", + ")\n" ], "metadata": { "collapsed": false }, "id": "8d90932312c418ee", - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Apply perturbation to the material" - ], - "metadata": { - "collapsed": false - }, - "id": "7695d5d1df6be2e3" - }, - { - "cell_type": "code", "outputs": [], - "source": [ - "from mat3ra.made.tools.build.perturbation import create_perturbation\n", - "\n", - "material_with_custom_perturbation = create_perturbation(configuration_custom, builder)" - ], - "metadata": { - "collapsed": false - }, - "id": "69ccc90b8c5c1191", "execution_count": null }, { @@ -257,17 +227,17 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "visualize([\n", - " {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\"},\n", - " {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\", \"rotation\": \"-90x\"}\n", + " {\"material\": material_with_perturbation, \"title\": f\"Material with custom perturbation\"},\n", + " {\"material\": material_with_perturbation, \"title\": f\"Material with custom perturbation\", \"rotation\": \"-90x\"}\n", "])" ], "metadata": { "collapsed": false }, "id": "cbfe0878a16f6c83", + "outputs": [], "execution_count": null }, { @@ -282,16 +252,16 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", - "set_materials(material_with_custom_perturbation)" + "set_materials(material_with_perturbation)" ], "metadata": { "collapsed": false }, "id": "29dfa0a329cca2fa", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_point_defect.ipynb b/other/materials_designer/create_point_defect.ipynb index f09fa057b..92d465612 100644 --- a/other/materials_designer/create_point_defect.ipynb +++ b/other/materials_designer/create_point_defect.ipynb @@ -2,8 +2,12 @@ "cells": [ { "cell_type": "markdown", + "id": "f2e1e795020d7b3f", + "metadata": { + "collapsed": false + }, "source": [ - "# Create point defects in a bulk material\n", + "# Create Multiple Point Defects in a Bulk Material\n", "\n", "Create a vacancy, add substitution or interstitial atom to provided Material.\n", "\n", @@ -18,72 +22,72 @@ "\n", "1. For more information, see [Introduction](Introduction.ipynb)\n", "\n" - ], - "metadata": { - "collapsed": false - }, - "id": "f2e1e795020d7b3f" + ] }, { "cell_type": "markdown", + "id": "5e43ff288847b784", + "metadata": { + "collapsed": false + }, "source": [ "## 1. Prepare the Environment\n", "### 1.1. Set up defects parameters \n", "Defect Configuration parameters are described in [Defect Configuration](https://github.com/Exabyte-io/made/blob/8196b759242551c77d1791bf5bd2f4150763cfef/src/py/mat3ra/made/tools/build/defect/configuration.py#L102)." - ], - "metadata": { - "collapsed": false - }, - "id": "5e43ff288847b784" + ] }, { "cell_type": "code", + "id": "9d8b1890b34d850a", + "metadata": { + "collapsed": false + }, "source": [ "# Selected material will be used as a unit cell to create a supercell first.\n", "SUPERCELL_MATRIX = [[3, 0, 0], [0, 3, 0], [0, 0, 3]]\n", "\n", - "# List of dictionaries with defect parameters\n", "DEFECT_CONFIGS = [\n", " {\n", - " \"defect_type\": \"substitution\", # (e.g. \"vacancy\", \"substitution\", \"interstitial\")\n", - " \"chemical_element\": \"C\", # Substitution element\n", - " \"approximate_coordinate\": [0.0, 0.0, 0.0], # Approx. coord that will be resolved to the closest site\n", - " \"use_cartesian_coordinates\": True, # Use cartesian or crystal coordinates\n", + " \"type\": \"substitution\",\n", + " \"coordinate\": [0.0, 0.0, 0.0], # Crystal coordinates\n", + " \"element\": \"C\",\n", + " \"placement_method\": \"closest_site\",\n", + " },\n", + " \n", + " {\n", + " \"type\": \"vacancy\",\n", + " \"coordinate\": [0.25, 0.25, 0.25], # Crystal coordinates \n", + " \"placement_method\": \"closest_site\",\n", + " },\n", + " \n", + " {\n", + " \"type\": \"interstitial\",\n", + " \"coordinate\": [0.75, 0.75, 0.75], # Crystal coordinates\n", + " \"element\": \"N\",\n", + " \"placement_method\": \"voronoi_site\",\n", " },\n", - "\n", - " # Uncomment the next lines to create more defects\n", - " # {\n", - " # \"defect_type\": \"vacancy\", # Remove an atom at a specific site\n", - " # \"site_id\": 0, # Index of the atom in the host material\n", - " # },\n", - " # {\n", - " # \"defect_type\": \"interstitial\", # Add an atom at an interstitial site\n", - " # \"coordinate\": [0.25, 0.25, 0.25], # Exact position\n", - " # \"use_cartesian_coordinates\": False, # Use cartesian or crystal coordinates\n", - " # \"chemical_element\": \"N\", # Add interstitial atom\n", - " # }\n", "]" ], - "metadata": { - "collapsed": false - }, - "id": "9d8b1890b34d850a", "outputs": [], "execution_count": null }, { "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))." - ], + "id": "bb64de5ff32649f8", "metadata": { "collapsed": false }, - "id": "bb64de5ff32649f8" + "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))." + ] }, { "cell_type": "code", + "id": "ef664b14457530fd", + "metadata": { + "collapsed": false + }, "source": [ "import sys\n", "\n", @@ -96,50 +100,47 @@ "\n", " await install_packages(\"create_point_defect.ipynb\")" ], - "metadata": { - "collapsed": false - }, - "id": "ef664b14457530fd", "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 1.3. Get input materials\n", - "Materials are loaded with `get_materials()`." - ], + "id": "919ad7af8dceeedd", "metadata": { "collapsed": false }, - "id": "919ad7af8dceeedd" + "source": "### 1.3. Get input materials" }, { "cell_type": "code", + "id": "be38fdda1984c654", + "metadata": { + "collapsed": false + }, "source": [ "from utils.jupyterlite import get_materials\n", "\n", "materials = get_materials(globals())" ], - "metadata": { - "collapsed": false - }, - "id": "be38fdda1984c654", "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 1.4. Create and preview Supercell" - ], + "id": "a132fe0ef8bbf0d0", "metadata": { "collapsed": false }, - "id": "a132fe0ef8bbf0d0" + "source": [ + "### 1.4. Create and preview Supercell" + ] }, { "cell_type": "code", + "id": "e2d24109d3068c9e", + "metadata": { + "collapsed": false + }, "source": [ "from utils.visualize import visualize_materials as visualize\n", "from mat3ra.made.tools.build.supercell import create_supercell\n", @@ -148,115 +149,121 @@ "supercell = create_supercell(unit_cell, supercell_matrix=SUPERCELL_MATRIX)\n", "visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")" ], - "metadata": { - "collapsed": false - }, - "id": "e2d24109d3068c9e", "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 2. Create the Defect\n", - "### 2.1. Initialize Configuration and Builder parameters" - ], + "id": "5da5b0380583c952", "metadata": { "collapsed": false }, - "id": "5da5b0380583c952" + "source": [ + "## 2. Create Multiple Defects\n", + "### 2.1. Prepare defect dictionaries for creation" + ] }, { "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.defect import PointDefectConfiguration\n", - "from mat3ra.made.tools.build.defect.builders import PointDefectBuilderParameters\n", - "\n", - "defect_configurations = [PointDefectConfiguration.from_dict(supercell, defect) for defect in DEFECT_CONFIGS]\n", - "\n", - "defect_builder_parameters = PointDefectBuilderParameters(center_defect=False)" - ], + "id": "e385e50ae11ed2b9", "metadata": { "collapsed": false }, - "id": "e385e50ae11ed2b9", + "source": [ + "print(\"Defect configurations:\")\n", + "for i, defect_dict in enumerate(DEFECT_CONFIGS):\n", + " print(f\"\\n{i+1}. {defect_dict['type'].upper()}:\")\n", + " print(f\" - Coordinate: {defect_dict['coordinate']}\")\n", + " print(f\" - Resolution method: {defect_dict['placement_method']}\")\n", + " if \"element\" in defect_dict:\n", + " print(f\" - Element: {defect_dict['element']}\")\n", + " \n", + "print(f\"\\nTotal defects to create: {len(DEFECT_CONFIGS)}\")" + ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 2.2. Create the defects" - ], + "id": "489b51f0ee122c48", "metadata": { "collapsed": false }, - "id": "489b51f0ee122c48" + "source": [ + "### 2.2. Create multiple defects using the newer approach" + ] }, { "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.defect import create_defects\n", - "\n", - "material_with_defect = create_defects(builder_parameters=defect_builder_parameters,\n", - " configurations=defect_configurations)" - ], + "id": "a990fa35742d7269", "metadata": { "collapsed": false }, - "id": "a990fa35742d7269", + "source": [ + "from mat3ra.made.tools.build.defect.point.helpers import create_multiple_defects\n", + "\n", + "material_with_defects = create_multiple_defects(\n", + " material=supercell,\n", + " defect_dicts=DEFECT_CONFIGS,\n", + ")\n", + "\n", + "print(f\"Original atoms: {len(supercell.basis.elements.ids)}\")\n", + "print(f\"Final atoms: {len(material_with_defects.basis.elements.ids)}\")" + ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 3. Visualize Result(s)" - ], + "id": "462549d016073446", "metadata": { "collapsed": false }, - "id": "462549d016073446" + "source": [ + "## 3. Visualize Result(s)" + ] }, { "cell_type": "code", + "id": "509b18661a069e42", + "metadata": { + "collapsed": false + }, "source": [ "from utils.visualize import visualize_materials as visualize\n", "\n", "visualize([{\"material\": supercell, \"title\": \"Original material\"},\n", - " {\"material\": material_with_defect, \"title\": f\"Material with defect\"}],\n", + " {\"material\": material_with_defects, \"title\": f\"Material with defects\"}],\n", " rotation=\"-90x\")\n", "visualize([{\"material\": supercell, \"title\": \"Original material\"},\n", - " {\"material\": material_with_defect, \"title\": f\"Material with defect\"}])" + " {\"material\": material_with_defects, \"title\": f\"Material with defects\"}])" ], - "metadata": { - "collapsed": false - }, - "id": "509b18661a069e42", "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 4. Pass data to the outside runtime" - ], + "id": "d381df29a6bbdd82", "metadata": { "collapsed": false }, - "id": "d381df29a6bbdd82" + "source": [ + "## 4. Pass data to the outside runtime" + ] }, { "cell_type": "code", + "id": "61daa5afcbc078a9", + "metadata": { + "collapsed": false + }, "source": [ "from utils.jupyterlite import set_materials\n", "\n", - "set_materials([material_with_defect])" + "# Set the material name and pass to outside runtime\n", + "material_with_defects.name = f\"{unit_cell.name} with {len(DEFECT_CONFIGS)} defects\"\n", + "set_materials([material_with_defects])" ], - "metadata": { - "collapsed": false - }, - "id": "61daa5afcbc078a9", "outputs": [], "execution_count": null } diff --git a/other/materials_designer/create_point_defect_pair.ipynb b/other/materials_designer/create_point_defect_pair.ipynb index 8f96decdb..9c294c884 100644 --- a/other/materials_designer/create_point_defect_pair.ipynb +++ b/other/materials_designer/create_point_defect_pair.ipynb @@ -37,47 +37,46 @@ "id": "5e43ff288847b784" }, { + "metadata": {}, "cell_type": "code", "source": [ + "from types import SimpleNamespace\n", + "\n", "# Selected material will be used as a unit cell to create a supercell first.\n", "SUPERCELL_MATRIX = [[3, 0, 0], [0, 3, 0], [0, 0, 3]]\n", "\n", "# List of dictionaries with defect parameters\n", - "PRIMARY_DEFECT_CONFIG = {\n", - " \"defect_type\": \"vacancy\",\n", - " \"approximate_coordinate\": [0.5, 0.5, 0.5],\n", - " \"use_cartesian_coordinates\": False, # Use cartesian or crystal coordinates\n", + "PRIMARY_DEFECT_CONFIG = SimpleNamespace(\n", + " defect_type=\"vacancy\",\n", + " coordinate=[0.5, 0.5, 0.5], # Approx. coord that will be resolved to the closest site\n", + " use_cartesian_coordinates=False, # Use cartesian or crystal coordinates\n", " # \"site_id\": 0, # Index of the atom in the host material\n", " # \"coordinate\": None, # Exact position (override the approximate coordinate)\n", - "}\n", + ")\n", "\n", - "SECONDARY_DEFECT_CONFIG = {\n", - " \"defect_type\": \"substitution\",\n", - " \"approximate_coordinate\": [0.55, 0.55, 0.55],\n", - " \"chemical_element\": \"C\",\n", - " # \"site_id\": 0,\n", - " # \"coordinate\": None,\n", - "}" + "SECONDARY_DEFECT_CONFIG = SimpleNamespace(\n", + " defect_type=\"substitution\",\n", + " approximate_coordinate=[0.15, 0.15, 0.15], # Approx. coord that will be resolved to the closest site\n", + " chemical_element=\"C\", # Element to substitute\n", + " # \"site_id\": 0, # Index of the atom in the host material\n", + " # \"coordinate\": None, # Exact position (override the approximate coordinate)\n", + ")" ], - "metadata": { - "collapsed": false - }, - "id": "9d8b1890b34d850a", + "id": "71f275fbc0163e6f", "outputs": [], "execution_count": null }, { + "metadata": {}, "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" + "id": "709d92aa693bd65f" }, { + "metadata": {}, "cell_type": "code", "source": [ "import sys\n", @@ -91,10 +90,7 @@ "\n", " await install_packages(\"create_point_defect.ipynb\")" ], - "metadata": { - "collapsed": false - }, - "id": "ef664b14457530fd", + "id": "d499bc9a7f6855f7", "outputs": [], "execution_count": null }, @@ -162,63 +158,38 @@ "id": "5da5b0380583c952" }, { + "metadata": {}, "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.defect.configuration import PointDefectPairConfiguration, PointDefectConfiguration\n", - "from mat3ra.made.tools.build.defect.builders import PointDefectBuilderParameters\n", - "\n", - "primary_defect_configuration = PointDefectConfiguration.from_dict(supercell, PRIMARY_DEFECT_CONFIG)\n", - "secondary_defect_configuration = PointDefectConfiguration.from_dict(supercell, SECONDARY_DEFECT_CONFIG)\n", - "\n", - "point_defect_pair_configuration = PointDefectPairConfiguration(\n", - " primary_defect_configuration=primary_defect_configuration,\n", - " secondary_defect_configuration=secondary_defect_configuration\n", - ")\n", - "\n", - "defect_builder_parameters = PointDefectBuilderParameters(center_defect=False)" - ], - "metadata": { - "collapsed": false - }, - "id": "e385e50ae11ed2b9", - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "### 2.2. Create the defects" - ], - "metadata": { - "collapsed": false - }, - "id": "489b51f0ee122c48" - }, - { - "cell_type": "code", - "source": [ - "from mat3ra.made.tools.build.defect.builders import PointDefectPairBuilder\n", - "\n", - "material_with_defect = PointDefectPairBuilder(defect_builder_parameters).get_material(point_defect_pair_configuration)" - ], - "metadata": { - "collapsed": false - }, - "id": "a990fa35742d7269", + "from mat3ra.made.tools.build.defect.pair_defect.helpers import create_pair_defect\n", + "\n", + "material_with_defect = create_pair_defect(\n", + " material=supercell,\n", + " defect_type_1=PRIMARY_DEFECT_CONFIG.defect_type,\n", + " coordinate_1=PRIMARY_DEFECT_CONFIG.coordinate,\n", + " element_1=PRIMARY_DEFECT_CONFIG.chemical_element if hasattr(PRIMARY_DEFECT_CONFIG, \"chemical_element\") else None,\n", + " placement_method_1=PRIMARY_DEFECT_CONFIG.placement_method if hasattr(PRIMARY_DEFECT_CONFIG,\n", + " 'placement_method') else None,\n", + " defect_type_2=SECONDARY_DEFECT_CONFIG.defect_type,\n", + " coordinate_2=SECONDARY_DEFECT_CONFIG.approximate_coordinate,\n", + " element_2=SECONDARY_DEFECT_CONFIG.chemical_element if hasattr(SECONDARY_DEFECT_CONFIG,\n", + " \"chemical_element\") else None,\n", + " placement_method_2=SECONDARY_DEFECT_CONFIG.placement_method if hasattr(SECONDARY_DEFECT_CONFIG,\n", + " 'placement_method') else None,\n", + ")" + ], + "id": "c4f50fb621da6474", "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "## 3. Visualize Result(s)" - ], - "metadata": { - "collapsed": false - }, - "id": "462549d016073446" + "source": "## 3. Visualize Result(s)", + "id": "ae5f5d5e9be9113" }, { + "metadata": {}, "cell_type": "code", "source": [ "from utils.visualize import visualize_materials as visualize\n", @@ -229,10 +200,7 @@ "visualize([{\"material\": supercell, \"title\": \"Original material\"},\n", " {\"material\": material_with_defect, \"title\": f\"Material with defect\"}])" ], - "metadata": { - "collapsed": false - }, - "id": "509b18661a069e42", + "id": "8308ef3260816859", "outputs": [], "execution_count": null }, diff --git a/other/materials_designer/create_slab.ipynb b/other/materials_designer/create_slab.ipynb index fde1ea3fc..c0235d5a1 100644 --- a/other/materials_designer/create_slab.ipynb +++ b/other/materials_designer/create_slab.ipynb @@ -51,7 +51,9 @@ "USE_ORTHOGONAL_C = True\n", "USE_CONVENTIONAL_CELL = True\n", "\n", - "# Index of the termination to be selected\n", + "# Stoichiometric formula of the slab termination to be used.\n", + "SLAB_TERMINATION_FORMULA = None\n", + "# if None, the index of all possible terminations will be used\n", "TERMINATION_INDEX = 0" ], "metadata": { @@ -250,11 +252,15 @@ { "cell_type": "code", "source": [ + "from mat3ra.made.tools.build.slab.termination_utils import select_slab_termination\n", "from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n", "\n", "termination_index = TERMINATION_INDEX\n", - "\n", "termination = slab_terminations[termination_index]\n", + "\n", + "if SLAB_TERMINATION_FORMULA:\n", + " termination = select_slab_termination(slab_terminations, SLAB_TERMINATION_FORMULA)\n", + "\n", "if IS_TERMINATIONS_SELECTION_INTERACTIVE:\n", " if sys.platform == \"emscripten\":\n", " termination = await ui_prompt_select_array_element_by_index_pyodide(slab_terminations, element_name=\"termination\")\n", @@ -302,24 +308,6 @@ "outputs": [], "execution_count": null }, - { - "metadata": {}, - "cell_type": "markdown", - "source": "### 3.2. Create slab supercell", - "id": "677536f3b6243679" - }, - { - "metadata": {}, - "cell_type": "code", - "source": [ - "from mat3ra.made.tools.operations.core.unary import supercell\n", - "\n", - "slab_supercell = supercell(slab, XY_SUPERCELL_MATRIX)" - ], - "id": "b67c1b26078499fd", - "outputs": [], - "execution_count": null - }, { "cell_type": "markdown", "source": "## 4. Visualize the resulting slab", @@ -330,7 +318,7 @@ }, { "cell_type": "code", - "source": "visualize(slab_supercell, repetitions=[1, 1, 1], rotation=\"0x\")", + "source": "visualize(slab, repetitions=[1, 1, 1], rotation=\"0x\")", "metadata": { "collapsed": false }, @@ -352,7 +340,7 @@ "cell_type": "code", "source": [ "from utils.jupyterlite import set_materials\n", - "set_materials(slab_supercell)" + "set_materials(slab)" ], "metadata": { "collapsed": false diff --git a/other/materials_designer/create_supercell.ipynb b/other/materials_designer/create_supercell.ipynb index a346210eb..b1a69eff4 100644 --- a/other/materials_designer/create_supercell.ipynb +++ b/other/materials_designer/create_supercell.ipynb @@ -32,7 +32,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "SUPERCELL_MATRIX = [\n", " [3, 0, 0], \n", @@ -47,7 +46,8 @@ "collapsed": false }, "id": "e93f72e7c37dea10", - "execution_count": 0 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -62,7 +62,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", @@ -78,7 +77,8 @@ "collapsed": false }, "id": "9eb0650f7183279c", - "execution_count": 0 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -92,7 +92,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", @@ -103,7 +102,8 @@ "collapsed": false }, "id": "4b72580121ca40d0", - "execution_count": 0 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -117,7 +117,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials as visualize\n", "repetitions = SCALING_FACTOR if SCALING_FACTOR else [3, 3, 1]\n", @@ -128,7 +127,8 @@ "collapsed": false }, "id": "d3cba46f185c1a1b", - "execution_count": 0 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -142,7 +142,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from mat3ra.made.tools.build.supercell import create_supercell\n", "\n", @@ -155,7 +154,8 @@ "collapsed": false }, "id": "2795d5bdbbaafbe6", - "execution_count": 0 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -169,7 +169,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")\n", "visualize(supercell, repetitions=[1, 1, 1], rotation=\"-90x\")" @@ -178,7 +177,8 @@ "collapsed": false }, "id": "aea078560283ca95", - "execution_count": 0 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -192,7 +192,6 @@ }, { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "set_materials(supercell)" @@ -201,7 +200,8 @@ "collapsed": false }, "id": "cdaf612bc6198546", - "execution_count": 0 + "outputs": [], + "execution_count": null } ], "metadata": { diff --git a/other/materials_designer/create_terrace_defect.ipynb b/other/materials_designer/create_terrace_defect.ipynb index e0ef7ef11..de4d89fe1 100644 --- a/other/materials_designer/create_terrace_defect.ipynb +++ b/other/materials_designer/create_terrace_defect.ipynb @@ -39,6 +39,7 @@ "id": "ff0f33c4e6ac1303" }, { + "metadata": {}, "cell_type": "code", "source": [ "# Material selection\n", @@ -56,7 +57,7 @@ " \"miller_indices\": (0, 0, 1),\n", " \"thickness\": 6,\n", " \"vacuum\": 10.0,\n", - " \"use_orthogonal_z\": True,\n", + " \"USE_ORTHOGONAL_C\": True,\n", " \"xy_supercell_matrix\": [[5, 0], [0, 5]]\n", "}\n", "\n", @@ -64,16 +65,9 @@ "SHOW_INTERMEDIATE_STEPS = True\n", "CELL_REPETITIONS_FOR_VISUALIZATION = [3, 3, 1] # Structure repeat in view" ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:53:55.899740Z", - "start_time": "2025-05-13T22:53:55.894773Z" - } - }, - "id": "dd6ca344ae34a2d6", + "id": "581cb3ccf2a95f8a", "outputs": [], - "execution_count": 1 + "execution_count": null }, { "cell_type": "markdown", @@ -101,15 +95,11 @@ " await install_packages(\"\")" ], "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:53:56.024643Z", - "start_time": "2025-05-13T22:53:56.021253Z" - } + "collapsed": false }, "id": "38574beae9a769cd", "outputs": [], - "execution_count": 2 + "execution_count": null }, { "cell_type": "markdown", @@ -122,97 +112,42 @@ "id": "c0eab57550f40708" }, { + "metadata": {}, "cell_type": "code", "source": [ "from utils.jupyterlite import get_materials\n", "\n", - "materials = get_materials(globals())" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:53:56.404034Z", - "start_time": "2025-05-13T22:53:56.029464Z" - } - }, - "id": "f2479655b99cca48", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0: 0-Ni\n", - "1: 1-Graphene\n", - "2: C2(001)-Ni4(111), Interface\n", - "3: Ni26 C1, Substitution C Defect\n", - "4: Ni4(001), termination Ni_P4:mmm_2, Slab\n", - "5: O8Zr4(011), termination O2_P2:m_1, Slab\n", - "Retrieved 6 materials.\n" - ] - } + "materials = get_materials(globals())\n", + "material = materials[MATERIAL_INDEX]" ], - "execution_count": 3 + "id": "2eed23af0ec63634", + "outputs": [], + "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 1.4. Create a slab if the input material is not a slab" - ], - "metadata": { - "collapsed": false - }, - "id": "4282a853c29a1501" + "source": "### 1.4. Create a slab if the input material is not a slab", + "id": "2c0d3e29ca42f099" }, { + "metadata": {}, "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.slab import create_slab_if_not, SlabConfiguration\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab_if_not, SlabConfiguration\n", "\n", - "default_slab_config = SlabConfiguration(\n", - " bulk=materials[0],\n", + "default_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=material,\n", " miller_indices=DEFAULT_SLAB_PARAMETERS[\"miller_indices\"],\n", " number_of_layers=DEFAULT_SLAB_PARAMETERS[\"thickness\"],\n", " vacuum=DEFAULT_SLAB_PARAMETERS[\"vacuum\"],\n", - " use_orthogonal_z=DEFAULT_SLAB_PARAMETERS[\"use_orthogonal_z\"],\n", - " xy_supercell_matrix=DEFAULT_SLAB_PARAMETERS[\"xy_supercell_matrix\"]\n", ")\n", "\n", - "slab = create_slab_if_not(materials[0], default_slab_config)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:53:58.127131Z", - "start_time": "2025-05-13T22:53:56.411318Z" - } - }, - "id": "80b7b827c2b390c3", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The material is not a slab. Creating a new slab...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/mat3ra/code/GREEN/api-examples/.venv-3.11.2/lib/python3.11/site-packages/spglib/spglib.py:115: DeprecationWarning: dict interface (SpglibDataset['number']) is deprecated.Use attribute interface ({self.__class__.__name__}.{key}) instead\n", - " warnings.warn(\n", - "/Users/mat3ra/code/GREEN/api-examples/.venv-3.11.2/lib/python3.11/site-packages/spglib/spglib.py:115: DeprecationWarning: dict interface (SpglibDataset['international']) is deprecated.Use attribute interface ({self.__class__.__name__}.{key}) instead\n", - " warnings.warn(\n", - "/Users/mat3ra/code/GREEN/api-examples/.venv-3.11.2/lib/python3.11/site-packages/spglib/spglib.py:115: DeprecationWarning: dict interface (SpglibDataset['wyckoffs']) is deprecated.Use attribute interface ({self.__class__.__name__}.{key}) instead\n", - " warnings.warn(\n", - "/Users/mat3ra/code/GREEN/api-examples/.venv-3.11.2/lib/python3.11/site-packages/spglib/spglib.py:115: DeprecationWarning: dict interface (SpglibDataset['equivalent_atoms']) is deprecated.Use attribute interface ({self.__class__.__name__}.{key}) instead\n", - " warnings.warn(\n", - "/Users/mat3ra/code/GREEN/api-examples/.venv-3.11.2/lib/python3.11/site-packages/spglib/spglib.py:115: DeprecationWarning: dict interface (SpglibDataset['rotations']) is deprecated.Use attribute interface ({self.__class__.__name__}.{key}) instead\n", - " warnings.warn(\n" - ] - } + "slab = create_slab_if_not(material, default_slab_config)" ], - "execution_count": 4 + "id": "92ad17e2b0032fda", + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -235,51 +170,11 @@ " visualize_materials(slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION, rotation=\"-90x\")" ], "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:54:00.098213Z", - "start_time": "2025-05-13T22:53:58.147449Z" - } + "collapsed": false }, "id": "16bb968a93de4b9", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initial slab structure:\n" - ] - }, - { - "data": { - "text/plain": [ - "GridBox(children=(VBox(children=(Label(value='Ni600 - Material - rotation: 0x,0y,0z', layout=Layout(align_self…" - ], - "application/vnd.jupyter.widget-view+json": { - "version_major": 2, - "version_minor": 0, - "model_id": "5d8f3702971441c0948961611e5b5e05" - } - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "GridBox(children=(VBox(children=(Label(value='Ni600 - Material - rotation: -90x', layout=Layout(align_self='ce…" - ], - "application/vnd.jupyter.widget-view+json": { - "version_major": 2, - "version_minor": 0, - "model_id": "513069d61748466dbeb41e1b657551dc" - } - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "execution_count": 5 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -295,44 +190,33 @@ { "cell_type": "code", "source": [ - "from mat3ra.made.tools.build.defect.builders import TerraceSlabDefectConfiguration, TerraceSlabDefectBuilder\n", + "from mat3ra.made.tools.build.defect.terrace.helpers import create_terrace\n", "\n", - "config = TerraceSlabDefectConfiguration(\n", - " crystal=slab,\n", + "terrace_slab = create_terrace(\n", + " slab=slab,\n", " cut_direction=CUT_DIRECTION,\n", " pivot_coordinate=PIVOT_COORDINATE,\n", " number_of_added_layers=NUMBER_OF_ADDED_LAYERS,\n", " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES,\n", " rotate_to_match_pbc=ROTATE_TO_MATCH_PBC\n", - ")\n", - "\n", - "builder = TerraceSlabDefectBuilder()" + ")\n" ], "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:54:00.133631Z", - "start_time": "2025-05-13T22:54:00.107036Z" - } + "collapsed": false }, "id": "c318fd03c7e667df", "outputs": [], - "execution_count": 6 + "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 2.2. Generate terrace defect\n" - ], - "metadata": { - "collapsed": false - }, - "id": "b9df79c67a870181" + "source": "## 2.2. Print the parameters of the created terrace defect", + "id": "8547862478ab0c7f" }, { "cell_type": "code", "source": [ - "terrace_slab = builder.get_material(config)\n", "\n", "print(\"\\nTerrace defect created with:\")\n", "print(f\"Cut direction: {CUT_DIRECTION}\")\n", @@ -341,28 +225,11 @@ "print(f\"Number of atoms: {len(terrace_slab.basis.elements.ids)}\")" ], "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:54:00.552490Z", - "start_time": "2025-05-13T22:54:00.226564Z" - } + "collapsed": false }, "id": "256bc04ff0aa1810", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Terrace defect created with:\n", - "Cut direction: [1, 0, 0]\n", - "Pivot point: [0.5, 0.5, 0.5]\n", - "Added layers: 1\n", - "Number of atoms: 654\n" - ] - } - ], - "execution_count": 7 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -382,51 +249,11 @@ "visualize_materials(terrace_slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION, rotation=\"-90x\")" ], "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:54:02.576772Z", - "start_time": "2025-05-13T22:54:00.605512Z" - } + "collapsed": false }, "id": "4ffdd8589b02de16", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Final structure with terrace:\n" - ] - }, - { - "data": { - "text/plain": [ - "GridBox(children=(VBox(children=(Label(value='Ni654 - Material - rotation: 0x,0y,0z', layout=Layout(align_self…" - ], - "application/vnd.jupyter.widget-view+json": { - "version_major": 2, - "version_minor": 0, - "model_id": "7d35ca91ea174c9fb90877b4562f60ba" - } - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "GridBox(children=(VBox(children=(Label(value='Ni654 - Material - rotation: -90x', layout=Layout(align_self='ce…" - ], - "application/vnd.jupyter.widget-view+json": { - "version_major": 2, - "version_minor": 0, - "model_id": "211766fcd37a42fc92982e958157b9ee" - } - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "execution_count": 8 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -439,30 +266,16 @@ "id": "d65865cbab99478" }, { + "metadata": {}, "cell_type": "code", "source": [ "from utils.jupyterlite import set_materials\n", "\n", "set_materials(terrace_slab)" ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-05-13T22:54:02.627875Z", - "start_time": "2025-05-13T22:54:02.613998Z" - } - }, - "id": "e292358fe4803b4f", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Data for materials written to uploads/Ni4(001), termination Ni_P4:mmm_2, Slab, 1-step Terrace [1, 0, 0].json\n" - ] - } - ], - "execution_count": 9 + "id": "a57ecc6fe9c89ceb", + "outputs": [], + "execution_count": null } ], "metadata": { diff --git a/other/materials_designer/create_twisted_interface_with_commensurate_lattices.ipynb b/other/materials_designer/create_twisted_interface_with_commensurate_lattices.ipynb index b1777af4f..ba0593dbe 100644 --- a/other/materials_designer/create_twisted_interface_with_commensurate_lattices.ipynb +++ b/other/materials_designer/create_twisted_interface_with_commensurate_lattices.ipynb @@ -2,10 +2,14 @@ "cells": [ { "cell_type": "markdown", + "id": "536d623ca076bbdd", + "metadata": { + "collapsed": false + }, "source": [ " # Create a Twisted Interface with Commensurate Lattices\n", "\n", - "Use commensurate lattice matching algorithm to create twisted interfaces between two materials.\n", + "Use the `create_commensurate_interface` function to create twisted interfaces between two materials with commensurate lattice matching.\n", "\n", "

Usage

\n", "\n", @@ -19,39 +23,41 @@ "\n", "1. Prepare the Environment: Set up the notebook and install packages, preview the input materials\n", "1. Create and visualize the initial materials\n", - "1. Generate twisted interfaces with commensurate lattice matching\n", - "1. Select the interface with the desired twist angle and visualize it\n", + "1. Create a slab from the input material using `create_slab`\n", + "1. Generate twisted interface using `create_commensurate_interface` with the specified parameters\n", + "1. Visualize the final twisted interface\n", "\n", "## Notes\n", "\n", - "1. We perform commensurate lattice matching to find valid supercells that achieve the desired twist angle.\n", - "1. When the matching is finished, interfaces with angles close to the target are presented.\n", - "1. The algorithm searches for supercell matrices within specified size limits.\n", + "1. We first create a slab from the input material using specified Miller indices.\n", + "1. The `create_commensurate_interface` function performs commensurate lattice matching to find valid supercells.\n", + "1. The function searches for supercell matrices within specified size limits to achieve the target twist angle.\n", + "1. The interface is created with a specified gap between the twisted layers.\n", + "1. This approach follows the same pattern as the test suite for reliable results.\n", "1. For more information, see [Introduction](Introduction.ipynb)\n" - ], - "metadata": { - "collapsed": false - }, - "id": "536d623ca076bbdd" + ] }, { "cell_type": "markdown", + "id": "cc65bd914eecf844", + "metadata": { + "collapsed": false + }, "source": [ "## 1. Prepare the Environment\n", "### 1.1. Set up the notebook\n", "Set the following flags to control the notebook behavior\n" - ], - "metadata": { - "collapsed": false - }, - "id": "cc65bd914eecf844" + ] }, { "cell_type": "code", - "outputs": [], + "id": "be4987fdf0286ebb", + "metadata": { + "collapsed": false + }, "source": [ "# Material selection and basic parameters\n", - "FILM_INDEX = 0# Index in the list of materials, to access as materials[FILM_INDEX]\n", + "FILM_INDEX = 0 # Index in the list of materials, to access as materials[FILM_INDEX]\n", "SUBSTRATE_INDEX = None # Can be None to use same material as film\n", "\n", "# Twisted interface parameters\n", @@ -59,35 +65,43 @@ "INTERFACE_DISTANCE = 3.0 # in Angstroms\n", "INTERFACE_VACUUM = 20.0 # in Angstroms\n", "\n", - "# Search algorithm parameters\n", - "MAX_REPETITION = 6 # Maximum supercell matrix element value\n", + "# Commensurate interface parameters (following the test pattern)\n", "ANGLE_TOLERANCE = 2.5 # in degrees\n", + "MAX_SUPERCELL_MATRIX_INT = 6 # Maximum supercell matrix element value\n", "RETURN_FIRST_MATCH = True # If True, returns first solution within tolerance\n", "\n", + "# Slab creation parameters\n", + "MILLER_INDICES = (0, 0, 1) # Miller indices for slab creation\n", + "NUMBER_OF_LAYERS = 1 # Number of layers in the slab\n", + "USE_CONVENTIONAL_CELL = True\n", + "USE_ORTHOGONAL_C = True\n", + "\n", + "STACKING_DIRECTION = \"z\" # Stacking direction for the slab, can be \"x\", \"y\", or \"z\"\n", + "\n", "# Visualization parameters\n", "SHOW_INTERMEDIATE_STEPS = True\n", "VISUALIZE_REPETITIONS = [3, 3, 1]" ], - "metadata": { - "collapsed": false - }, - "id": "be4987fdf0286ebb", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 1.2. Install packages\n", - "Explanation is [here](under_the_hood.ipynb#1.2.-Install-packages)." - ], + "id": "5ffda79fd5cad69", "metadata": { "collapsed": false }, - "id": "5ffda79fd5cad69" + "source": [ + "### 1.2. Install packages\n", + "Explanation is [here](under_the_hood.ipynb#1.2.-Install-packages)." + ] }, { "cell_type": "code", - "outputs": [], + "id": "9f851434739f468a", + "metadata": { + "collapsed": false + }, "source": [ "import sys\n", "\n", @@ -99,51 +113,51 @@ " from mat3ra.utils.jupyterlite.packages import install_packages\n", " await install_packages(\"\")" ], - "metadata": { - "collapsed": false - }, - "id": "9f851434739f468a", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 1.3. Load and preview input materials\n", - "Explanation is [here](under_the_hood.ipynb#2.-Data-Exchange)." - ], + "id": "111e138010f911c", "metadata": { "collapsed": false }, - "id": "111e138010f911c" + "source": [ + "### 1.3. Load and preview input materials\n", + "Explanation is [here](under_the_hood.ipynb#2.-Data-Exchange)." + ] }, { "cell_type": "code", - "outputs": [], + "id": "d3a815612098f191", + "metadata": { + "collapsed": false + }, "source": [ "from utils.jupyterlite import get_materials\n", "\n", "materials = get_materials(globals())" ], - "metadata": { - "collapsed": false - }, - "id": "d3a815612098f191", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - " ## 2. Prepare Materials\n", - " ### 2.1. Select and visualize initial materials" - ], + "id": "8a01e2ba7092ecbe", "metadata": { "collapsed": false }, - "id": "8a01e2ba7092ecbe" + "source": [ + " ## 2. Prepare Materials\n", + " ### 2.1. Select and visualize initial materials" + ] }, { "cell_type": "code", - "outputs": [], + "id": "c920d29700ada27a", + "metadata": { + "collapsed": false + }, "source": [ "from utils.visualize import visualize_materials\n", "\n", @@ -155,139 +169,147 @@ " if substrate is not film:\n", " visualize_materials(substrate, repetitions=VISUALIZE_REPETITIONS)" ], - "metadata": { - "collapsed": false - }, - "id": "c920d29700ada27a", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 3. Generate Twisted Interface\n", - "### 3.1. Set up interface configuration and builder\n" - ], + "id": "ce38ef341148321", "metadata": { "collapsed": false }, - "id": "ce38ef341148321" + "source": [ + "## 3. Create Twisted Interface\n", + "### 3.1. Create slab and commensurate interface\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "d48726a8e99c5590", + "metadata": { + "collapsed": false + }, "source": [ - "from mat3ra.made.tools.build.interface.builders import CommensurateLatticeTwistedInterfaceBuilderParameters, \\\n", - " CommensurateLatticeTwistedInterfaceBuilder\n", - "from mat3ra.made.tools.build.interface.configuration import TwistedInterfaceConfiguration\n", + "from mat3ra.esse.models.core.reusable.axis_enum import AxisEnum\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab\n", + "from mat3ra.made.tools.build.interface.helpers import create_commensurate_interface\n", "\n", - "config = TwistedInterfaceConfiguration(\n", - " film=film,\n", - " substrate=film,\n", - " twist_angle=TARGET_TWIST_ANGLE,\n", - " distance_z=INTERFACE_DISTANCE\n", + "# Create slab from the material\n", + "slab = create_slab(\n", + " crystal=film,\n", + " miller_indices=MILLER_INDICES,\n", + " use_conventional_cell=USE_CONVENTIONAL_CELL,\n", + " use_orthogonal_c=USE_ORTHOGONAL_C,\n", + " number_of_layers=NUMBER_OF_LAYERS,\n", + " vacuum=0.0, # No vacuum in the slab initially\n", ")\n", "\n", - "params = CommensurateLatticeTwistedInterfaceBuilderParameters(\n", - " max_supercell_matrix_int=MAX_REPETITION,\n", - " angle_tolerance=ANGLE_TOLERANCE,\n", - " return_first_match=RETURN_FIRST_MATCH\n", - ")\n", + "print(f\"Created slab with {len(slab.basis.elements.ids)} atoms\")\n", "\n", - "builder = CommensurateLatticeTwistedInterfaceBuilder(build_parameters=params)" + "# Create the commensurate twisted interface using the function from the test\n", + "interface = create_commensurate_interface(\n", + " material=slab,\n", + " target_angle=TARGET_TWIST_ANGLE,\n", + " angle_tolerance=ANGLE_TOLERANCE,\n", + " max_repetition_int=MAX_SUPERCELL_MATRIX_INT,\n", + " return_first_match=RETURN_FIRST_MATCH,\n", + " direction=AxisEnum[STACKING_DIRECTION], # Stacking direction for the interface\n", + " gap=INTERFACE_DISTANCE, # Gap between layers\n", + ")" ], - "metadata": { - "collapsed": false - }, - "id": "d48726a8e99c5590", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 3.2. Generate and analyze interfaces\n" - ], + "id": "211084a2225f5e98", "metadata": { "collapsed": false }, - "id": "211084a2225f5e98" + "source": [ + "### 3.2. Interface creation results\n" + ] }, { "cell_type": "code", - "outputs": [], - "source": [ - "from utils.plot import plot_twisted_interface_solutions\n", - "\n", - "interfaces = builder.get_materials(config)\n", - "\n", - "print(f\"\\nFound {len(interfaces)} possible interface(s)\")\n", - "for i, interface in enumerate(interfaces):\n", - " actual_angle = interface.metadata.get(\"actual_twist_angle\", \"unknown\")\n", - " print(f\"\\nInterface {i+1}:\")\n", - " print(f\"Actual twist angle: {actual_angle}°\")\n", - " print(f\"Number of atoms: {len(interface.basis.elements.ids)}\")\n", - "\n", - "\n", - "if len(interfaces) > 0:\n", - " plot_twisted_interface_solutions(interfaces)" - ], + "id": "51acc60bf57a26d5", "metadata": { "collapsed": false }, - "id": "51acc60bf57a26d5", + "source": [ + "# The interface was created above using create_commensurate_interface\n", + "print(\"\\\\nInterface created successfully!\")\n", + "print(f\"Target twist angle: {TARGET_TWIST_ANGLE}°\")\n", + "print(f\"Number of atoms: {len(interface.basis.elements.ids)}\")\n", + "print(f\"Interface name: {interface.name}\")\n", + "\n", + "# Show intermediate visualization if requested\n", + "if SHOW_INTERMEDIATE_STEPS:\n", + " from utils.visualize import visualize_materials\n", + " print(\"\\\\nVisualizing the created interface:\")\n", + " visualize_materials(interface, repetitions=[1, 1, 1])\n", + " visualize_materials(interface, repetitions=[1, 1, 1], rotation=\"-90x\")" + ], + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "## 4. Preview the selected material\n", - "By default, the first interface is selected. You can change the selection by changing the `selected_interface` index." - ], + "id": "370d3acc33cb8907", "metadata": { "collapsed": false }, - "id": "370d3acc33cb8907" + "source": [ + "## 4. Preview the selected material\n", + "By default, the first interface is selected. You can change the selection by changing the `selected_interface` index." + ] }, { "cell_type": "code", - "outputs": [], + "id": "8fa34c8952f76602", + "metadata": { + "collapsed": false + }, "source": [ - "selected_interface = interfaces[0]\n", - "actual_angle = selected_interface.metadata.get(\"build\").get(\"configuration\").get(\"actual_twist_angle\")\n", + "# The interface is already created above, so just display final results\n", + "selected_interface = interface\n", + "\n", + "print(f\"Final Interface Summary:\")\n", "print(f\"Target angle: {TARGET_TWIST_ANGLE}°\")\n", - "print(f\"Actual angle: {actual_angle}°\")\n", "print(f\"Number of atoms: {len(selected_interface.basis.elements.ids)}\")\n", + "print(f\"Cell vectors:\\\\n{selected_interface.basis.cell.vector_arrays}\")\n", "\n", + "# Final visualization\n", + "from utils.visualize import visualize_materials\n", + "print(\"\\\\nFinal interface visualization:\")\n", "visualize_materials(selected_interface, repetitions=[1, 1, 1])\n", "visualize_materials(selected_interface, repetitions=[1, 1, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "8fa34c8952f76602", + "outputs": [], "execution_count": null }, { "cell_type": "markdown", - "source": [ - "### 5. Pass data to the outside runtime\n" - ], + "id": "87b8655d47b47019", "metadata": { "collapsed": false }, - "id": "87b8655d47b47019" + "source": [ + "### 5. Pass data to the outside runtime\n" + ] }, { "cell_type": "code", - "outputs": [], + "id": "28bebacd2e299c2c", + "metadata": { + "collapsed": false + }, "source": [ "from utils.jupyterlite import set_materials\n", "\n", "set_materials(selected_interface)" ], - "metadata": { - "collapsed": false - }, - "id": "28bebacd2e299c2c", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/create_twisted_interface_with_nanoribbons.ipynb b/other/materials_designer/create_twisted_interface_with_nanoribbons.ipynb index d89f56b42..13410c333 100644 --- a/other/materials_designer/create_twisted_interface_with_nanoribbons.ipynb +++ b/other/materials_designer/create_twisted_interface_with_nanoribbons.ipynb @@ -33,115 +33,112 @@ "id": "66b6951c7a25247c" }, { + "metadata": {}, "cell_type": "markdown", "source": [ "## 1. Prepare the Environment\n", - "### 1.1. Set up the notebook \n", - "Set the following flags to control the notebook behavior \n" + "### 1.1. Set up the notebook\n", + "Set the following flags to control the notebook behavior\n" ], + "id": "edec1dd3f8ff0782" + }, + { "metadata": { "collapsed": false }, - "id": "9b35a4b3a796c4ad" - }, - { "cell_type": "code", - "outputs": [], "source": [ "# Material selection and basic parameters\n", - "FILM_INDEX = 0 # Index in the list of materials, to access as materials[FILM_INDEX]\n", + "FILM_INDEX = 1 # Index in the list of materials, to access as materials[FILM_INDEX]\n", "SUBSTRATE_INDEX = None # Can be None to use same material as film\n", "\n", - "# Interface parameters\n", - "TWIST_ANGLE = 15.0 # in degrees\n", + "# Twisted interface parameters\n", + "TARGET_TWIST_ANGLE = 17.9 # in degrees\n", "INTERFACE_DISTANCE = 3.0 # in Angstroms\n", "INTERFACE_VACUUM = 20.0 # in Angstroms\n", "\n", "# Nanoribbon parameters\n", - "RIBBON_WIDTH = 5 # Width of the nanoribbon in unit cells\n", - "RIBBON_LENGTH = 10 # Length of the nanoribbon in unit cells\n", - "VACUUM_X = 5.0 # Vacuum along x on both sides, in Angstroms\n", - "VACUUM_Y = 5.0 # Vacuum along y on both sides, in Angstroms\n", + "RIBBON_WIDTH = 3 # Width of the nanoribbon in unit cells\n", + "RIBBON_LENGTH = 3 # Length of the nanoribbon in unit cells\n", + "VACUUM_WIDTH = 15.0 # Vacuum width around ribbons in Angstroms\n", + "VACUUM_LENGTH = 15.0 # Vacuum length around ribbons in Angstroms\n", + "VACUUM_X = 2.0 # Additional vacuum along x on both sides, in Angstroms\n", + "VACUUM_Y = 2.0 # Additional vacuum along y on both sides, in Angstroms\n", "\n", "# Visualization parameters\n", "SHOW_INTERMEDIATE_STEPS = True\n", - "VISUALIZE_REPETITIONS = [1, 1, 1]" + "VISUALIZE_REPETITIONS = [3, 3, 1]" ], - "metadata": { - "collapsed": false - }, - "id": "aaf8db99c7f77c5c", + "id": "746db0506f54aeb1", + "outputs": [], "execution_count": null }, { + "metadata": {}, "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))." + "Explanation is [here](under_the_hood.ipynb#1.2.-Install-packages)." ], + "id": "7e386d88600feb21" + }, + { "metadata": { "collapsed": false }, - "id": "eb558b99e13b8fdc" - }, - { "cell_type": "code", - "outputs": [], "source": [ "import sys\n", "\n", "if sys.platform == \"emscripten\":\n", " import micropip\n", - " \n", + "\n", " await micropip.install('mat3ra-api-examples', deps=False)\n", " await micropip.install('mat3ra-utils')\n", " from mat3ra.utils.jupyterlite.packages import install_packages\n", " await install_packages(\"\")" ], - "metadata": { - "collapsed": false - }, - "id": "bd2ed90db5f76f9b", + "id": "e5ab0c9b90ba9901", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "### 1.3. Load and preview input materials\n" + "### 1.3. Load and preview input materials\n", + "Explanation is [here](under_the_hood.ipynb#2.-Data-Exchange)." ], + "id": "b38044cae8eca705" + }, + { "metadata": { "collapsed": false }, - "id": "f201817580d12456" - }, - { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "\n", "materials = get_materials(globals())" ], - "metadata": { - "collapsed": false - }, - "id": "dcba2976f2baaa55", + "id": "d117934379d38f08", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "## 2. Prepare Materials\n", - "### 2.1. Select and visualize initial materials\n" + " ## 2. Prepare Materials\n", + " ### 2.1. Select and visualize initial materials" ], + "id": "90d5d8e7cf4f4378" + }, + { "metadata": { "collapsed": false }, - "id": "ee9e7669eecf3deb" - }, - { "cell_type": "code", - "outputs": [], "source": [ "from utils.visualize import visualize_materials\n", "\n", @@ -149,105 +146,129 @@ "substrate = materials[SUBSTRATE_INDEX] if SUBSTRATE_INDEX is not None else film\n", "\n", "if SHOW_INTERMEDIATE_STEPS:\n", - " print(\"\\nInitial material structure:\")\n", - " visualize_materials(film, repetitions=VISUALIZE_REPETITIONS)" + " visualize_materials(film, repetitions=VISUALIZE_REPETITIONS)\n", + " if substrate is not film:\n", + " visualize_materials(substrate, repetitions=VISUALIZE_REPETITIONS)" ], - "metadata": { - "collapsed": false - }, - "id": "27cc97b9bc42e73b", + "id": "d934062047d9cef", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "## 3. Generate Nanoribbon Interface\n", + "## 3. Generate Twisted Interface\n", "### 3.1. Set up interface configuration and builder\n" ], + "id": "7dc8fddf36069105" + }, + { "metadata": { "collapsed": false }, - "id": "6e7eb48ae2c4a49d" - }, - { "cell_type": "code", - "outputs": [], "source": [ - "from mat3ra.made.tools.build.interface.builders import NanoRibbonTwistedInterfaceBuilder\n", - "from mat3ra.made.tools.build.interface.configuration import NanoRibbonTwistedInterfaceConfiguration\n", + "from mat3ra.made.tools.build.interface import create_twisted_interface\n", + "# Create nanoribbons from the materials first\n", + "from mat3ra.made.tools.build.nanoribbon.helpers import create_nanoribbon\n", "\n", - "config = NanoRibbonTwistedInterfaceConfiguration(\n", - " film=film,\n", - " substrate=substrate,\n", - " twist_angle=TWIST_ANGLE,\n", - " distance_z=INTERFACE_DISTANCE,\n", - " ribbon_width=RIBBON_WIDTH,\n", - " ribbon_length=RIBBON_LENGTH,\n", - " vacuum_x=VACUUM_X,\n", - " vacuum_y=VACUUM_Y\n", + "# Create nanoribbons for both materials\n", + "nanoribbon1 = create_nanoribbon(\n", + " material=film,\n", + " width=RIBBON_WIDTH, # Width in unit cells\n", + " length=RIBBON_LENGTH, # Length in unit cells\n", + " vacuum_width=VACUUM_WIDTH, # Vacuum width in Angstroms\n", + " vacuum_length=VACUUM_LENGTH, # Vacuum length in Angstroms\n", + ")\n", + "\n", + "nanoribbon2 = create_nanoribbon(\n", + " material=substrate,\n", + " width=RIBBON_WIDTH, # Width in unit cells\n", + " length=RIBBON_LENGTH, # Length in unit cells\n", + " vacuum_width=VACUUM_WIDTH, # Vacuum width in Angstroms\n", + " vacuum_length=VACUUM_LENGTH, # Vacuum length in Angstroms\n", ")\n", "\n", - "builder = NanoRibbonTwistedInterfaceBuilder()" + "# Create the twisted interface using the manual approach\n", + "interface = create_twisted_interface(\n", + " material1=nanoribbon1,\n", + " material2=nanoribbon2,\n", + " angle=TARGET_TWIST_ANGLE,\n", + " vacuum_x=VACUUM_X,\n", + " vacuum_y=VACUUM_Y,\n", + " gap=INTERFACE_DISTANCE,\n", + ")" ], - "metadata": { - "collapsed": false - }, - "id": "99c0719450f2fbab", + "id": "28ed39605a8b29e", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", - "source": [ - "### 3.2. Generate and analyze interface\n" - ], + "source": "### 3.2. Generate and analyze interfaces\n", + "id": "53ced0bb45a414d5" + }, + { "metadata": { "collapsed": false }, - "id": "3f38902c015ac965" - }, - { "cell_type": "code", - "outputs": [], "source": [ - "interface = builder.get_material(config)\n", - "\n", - "print(\"\\nInterface created successfully!\")\n", - "print(f\"Twist angle: {TWIST_ANGLE}°\")\n", + "# The interface was already created above using the manual approach\n", + "print(\"\\\\nInterface created successfully!\")\n", + "print(f\"Target twist angle: {TARGET_TWIST_ANGLE}°\")\n", + "print(f\"Actual twist angle: {TARGET_TWIST_ANGLE}°\") # Since we set it manually\n", "print(f\"Number of atoms: {len(interface.basis.elements.ids)}\")\n", - "print(f\"Cell vectors:\\n{interface.basis.cell.vectors_as_array}\")\n", + "print(f\"Interface name: {interface.name}\")\n", "\n", + "# Show intermediate visualization if requested\n", "if SHOW_INTERMEDIATE_STEPS:\n", - " visualize_materials(interface, repetitions=VISUALIZE_REPETITIONS)\n", - " visualize_materials(interface, repetitions=VISUALIZE_REPETITIONS, rotation=\"-90x\")" + " from utils.visualize import visualize_materials\n", + " print(\"\\\\nVisualizing the created interface:\")\n", + " visualize_materials(interface, repetitions=[1, 1, 1])\n", + " visualize_materials(interface, repetitions=[1, 1, 1], rotation=\"-90x\")" ], - "metadata": { - "collapsed": false - }, - "id": "5a6e5f0a57746216", + "id": "5b234db939623503", + "outputs": [], "execution_count": null }, { + "metadata": {}, "cell_type": "markdown", "source": [ - "## 4. Pass data to the outside runtime\n" + "## 4. Preview the selected material\n", + "By default, the first interface is selected. You can change the selection by changing the `selected_interface` index." ], + "id": "3deba4978643a165" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### 5. Pass data to the outside runtime\n", + "id": "b1d073366e81aeaf" + }, + { "metadata": { "collapsed": false }, - "id": "c296c52797efcf29" - }, - { "cell_type": "code", - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", "set_materials(interface)" ], - "metadata": { - "collapsed": false - }, - "id": "6cf7cccac63dca3d", + "id": "4660ac6aad47b522", + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": "", + "id": "b231dde70694dd41", + "outputs": [], "execution_count": null } ], diff --git a/other/materials_designer/passivate_edge.ipynb b/other/materials_designer/passivate_edge.ipynb index 31c88e77e..dc218c8a0 100644 --- a/other/materials_designer/passivate_edge.ipynb +++ b/other/materials_designer/passivate_edge.ipynb @@ -34,8 +34,9 @@ ] }, { - "metadata": {}, "cell_type": "markdown", + "id": "f63b28f159207878", + "metadata": {}, "source": [ "## 1. Prepare the Environment\n", "### 1.1. Set up the notebook\n", @@ -43,12 +44,12 @@ "Coordination search radius shown on the image below:\n", "\n", "\"Coordination" - ], - "id": "f63b28f159207878" + ] }, { - "metadata": {}, "cell_type": "code", + "id": "7e8d8696bb1035e5", + "metadata": {}, "source": [ "# Enable interactive selection of coordination threshold\n", "IS_COORDINATION_SELECTION_INTERACTIVE = False\n", @@ -63,7 +64,7 @@ "# Undercoordinated atoms search algorithm parameters\n", "COORDINATION_THRESHOLD = 2 # Coordination threshold, below which passivation is applied to the atom\n", "COORDINATION_SEARCH_RADIUS = 3.0 # Distance to look for neighbors for coordination, in Angstroms\n", - "MAX_BONDS_TO_PASSIVATE = 1 # Maximum number of bonds to passivate\n", + "NUMBER_OF_BONDS_TO_PASSIVATE = 1 # Number of bonds to passivate per undercoordinated atom\n", "\n", "SYMMETRY_TOLERANCE = 0.1 # Tolerance for symmetry analysis of existing bonds\n", "\n", @@ -71,7 +72,6 @@ "SHOW_INTERMEDIATE_STEPS = True\n", "CELL_REPETITIONS_FOR_VISUALIZATION = [1, 1, 1] # Structure repeat in view" ], - "id": "7e8d8696bb1035e5", "outputs": [], "execution_count": null }, @@ -181,26 +181,24 @@ }, "source": [ "from utils.io import select_coordination_threshold\n", - "from mat3ra.made.tools.build.passivation import get_unique_coordination_numbers, PassivationConfiguration, \\\n", - " get_coordination_numbers_distribution\n", + "from mat3ra.made.tools.build.passivation.helpers import get_unique_coordination_numbers, get_coordination_numbers_distribution\n", "\n", "coordination_search_radius = None # Change this value according to the RDF plot if needed, Angstroms.\n", - "config = PassivationConfiguration(\n", - " slab=nanoribbon,\n", - " passivant=PASSIVANT,\n", - " bond_length=BOND_LENGTH\n", - ")\n", + "cutoff = coordination_search_radius or COORDINATION_SEARCH_RADIUS\n", + "\n", + "# Get coordination numbers using the newer approach\n", "coordination_numbers = get_unique_coordination_numbers(\n", - " configuration=config,\n", - " cutoff=coordination_search_radius or COORDINATION_SEARCH_RADIUS\n", + " material=nanoribbon,\n", + " cutoff=cutoff\n", ")\n", "print(f\"Unique coordination numbers: {coordination_numbers}\")\n", "\n", "cn_distribution = get_coordination_numbers_distribution(\n", - " configuration=config,\n", - " cutoff=coordination_search_radius or COORDINATION_SEARCH_RADIUS\n", + " material=nanoribbon,\n", + " cutoff=cutoff\n", ")\n", "print(f\"Coordination numbers distribution: {cn_distribution}\")\n", + "\n", "coordination_threshold = COORDINATION_THRESHOLD\n", "if IS_COORDINATION_SELECTION_INTERACTIVE:\n", " coordination_threshold = await select_coordination_threshold(\n", @@ -220,8 +218,8 @@ "collapsed": false }, "source": [ - "## 3. Create target material\n", - "### 3.1. Set up passivation configuration and builder\n" + "## 3. Create Passivated Material\n", + "### 3.1. Set up passivation parameters\n" ] }, { @@ -231,17 +229,18 @@ "collapsed": false }, "source": [ - "from mat3ra.made.tools.build.passivation.builders import CoordinationBasedPassivationBuilder, \\\n", - " CoordinationBasedPassivationBuilderParameters\n", + "passivation_params = {\n", + " \"shadowing_radius\": COORDINATION_SEARCH_RADIUS,\n", + " \"coordination_threshold\": coordination_threshold,\n", + " \"number_of_bonds_to_passivate\": NUMBER_OF_BONDS_TO_PASSIVATE,\n", + " \"symmetry_tolerance\": SYMMETRY_TOLERANCE\n", + "}\n", "\n", - "builder_params = CoordinationBasedPassivationBuilderParameters(\n", - " shadowing_radius=COORDINATION_SEARCH_RADIUS,\n", - " coordination_threshold=coordination_threshold,\n", - " bonds_to_passivate=MAX_BONDS_TO_PASSIVATE,\n", - " symmetry_tolerance=SYMMETRY_TOLERANCE\n", - ")\n", - "\n", - "builder = CoordinationBasedPassivationBuilder(build_parameters=builder_params)" + "print(f\"Passivation parameters:\")\n", + "print(f\" Shadowing radius: {passivation_params['shadowing_radius']} Å\")\n", + "print(f\" Coordination threshold: {passivation_params['coordination_threshold']}\")\n", + "print(f\" Number of bonds to passivate: {passivation_params['number_of_bonds_to_passivate']}\")\n", + "print(f\" Symmetry tolerance: {passivation_params['symmetry_tolerance']}\")" ], "outputs": [], "execution_count": null @@ -263,15 +262,21 @@ "collapsed": false }, "source": [ - "from mat3ra.made.tools.build.passivation import create_passivation\n", + "from mat3ra.made.tools.build.passivation.helpers import passivate_dangling_bonds\n", "\n", - "passivated_nanoribbon = create_passivation(config, builder)\n", + "passivated_nanoribbon = passivate_dangling_bonds(\n", + " material=nanoribbon,\n", + " passivant=PASSIVANT,\n", + " bond_length=BOND_LENGTH,\n", + " **passivation_params\n", + ")\n", "\n", "print(\"\\nPassivation completed:\")\n", "print(f\"Passivant used: {PASSIVANT}\")\n", "print(f\"Bond length: {BOND_LENGTH} Å\")\n", "print(f\"Original atoms: {len(nanoribbon.basis.elements.ids)}\")\n", - "print(f\"Final atoms: {len(passivated_nanoribbon.basis.elements.ids)}\")" + "print(f\"Final atoms: {len(passivated_nanoribbon.basis.elements.ids)}\")\n", + "print(f\"Passivant atoms added: {len(passivated_nanoribbon.basis.elements.ids) - len(nanoribbon.basis.elements.ids)}\")" ], "outputs": [], "execution_count": null diff --git a/other/materials_designer/passivate_slab.ipynb b/other/materials_designer/passivate_slab.ipynb index d736a3a8d..9f4d2d9bb 100644 --- a/other/materials_designer/passivate_slab.ipynb +++ b/other/materials_designer/passivate_slab.ipynb @@ -44,20 +44,21 @@ }, { "cell_type": "code", - "execution_count": 5, "id": "92b3518bebdcf547", "metadata": { "collapsed": false }, - "outputs": [], "source": [ + "\n", + "from mat3ra.made.tools.modify import translate_to_z_level\n", + "\n", "# Material selection\n", "MATERIAL_INDEX = 0 # Which material to use from input list\n", "\n", "# Passivation parameters\n", "PASSIVANT = \"H\" # Chemical symbol of passivating atom\n", "BOND_LENGTH = 1.0 # Distance from surface to passivant, in Angstroms\n", - "SURFACE = \"both\" # Which surface to passivate: \"top\", \"bottom\" or \"both\"\n", + "SURFACE = \"top\" # Which surface to passivate: \"top\", \"bottom\" or \"both\"\n", "\n", "# Surface detection parameters\n", "SHADOWING_RADIUS = 2.5 # Radius to exclude subsurface atoms, in Angstroms\n", @@ -70,14 +71,16 @@ " \"miller_indices\": (0, 0, 1),\n", " \"thickness\": 3,\n", " \"vacuum\": 10.0,\n", - " \"use_orthogonal_z\": True,\n", + " \"USE_ORTHOGONAL_C\": True,\n", " \"xy_supercell_matrix\": [[3, 0], [0, 3]]\n", "}\n", "\n", "# Visualization parameters\n", "SHOW_INTERMEDIATE_STEPS = True\n", "CELL_REPETITIONS_FOR_VISUALIZATION = [1, 1, 1] # Structure repeat in view" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -92,12 +95,10 @@ }, { "cell_type": "code", - "execution_count": 6, "id": "42863fe84bfab53c", "metadata": { "collapsed": false }, - "outputs": [], "source": [ "import sys\n", "\n", @@ -109,7 +110,9 @@ " from mat3ra.utils.jupyterlite.packages import install_packages\n", "\n", " await install_packages(\"\")" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -123,18 +126,18 @@ }, { "cell_type": "code", - "execution_count": null, "id": "a51551f4af6456c7", "metadata": { "collapsed": false }, - "outputs": [], "source": [ "from utils.jupyterlite import get_materials\n", "from utils.visualize import visualize_materials\n", "\n", "materials = get_materials(globals())" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -148,32 +151,31 @@ }, { "cell_type": "code", - "execution_count": null, "id": "ad71f877f76f0550", "metadata": { "collapsed": false }, - "outputs": [], "source": [ - "from mat3ra.made.tools.build.slab import create_slab_if_not, SlabConfiguration\n", + "from mat3ra.made.tools.build.slab.helpers import create_slab_if_not, SlabConfiguration\n", "\n", "material = materials[MATERIAL_INDEX]\n", - "default_slab_config = SlabConfiguration(\n", - " bulk=material,\n", + "default_slab_config = SlabConfiguration.from_parameters(\n", + " material_or_dict=material,\n", " miller_indices=DEFAULT_SLAB_PARAMETERS[\"miller_indices\"],\n", " number_of_layers=DEFAULT_SLAB_PARAMETERS[\"thickness\"],\n", " vacuum=DEFAULT_SLAB_PARAMETERS[\"vacuum\"],\n", - " use_orthogonal_z=DEFAULT_SLAB_PARAMETERS[\"use_orthogonal_z\"],\n", - " xy_supercell_matrix=DEFAULT_SLAB_PARAMETERS[\"xy_supercell_matrix\"]\n", ")\n", "\n", "slab = material if BYPASS_SLAB_CREATION else create_slab_if_not(material, default_slab_config)\n", + "slab = translate_to_z_level(slab, \"center\")\n", "\n", "if SHOW_INTERMEDIATE_STEPS:\n", " print(\"Initial slab structure:\")\n", " visualize_materials(slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION)\n", - " visualize_materials(slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION, rotation=\"-90x\")" - ] + " visualize_materials(slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION, rotation=\"-90x\")\n" + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -183,68 +185,36 @@ }, "source": [ "## 2. Create target material\n", - "### 2.1. Set up passivation configuration and builder\n" + "### 2.1. Passivate the slab surface\n" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "7e26e8e7fb8319a", + "id": "a4ed473eb2129ac4", "metadata": { "collapsed": false }, - "outputs": [], "source": [ - "from mat3ra.made.tools.build.passivation import (\n", - " PassivationConfiguration,\n", - " SurfacePassivationBuilder,\n", - " SurfacePassivationBuilderParameters\n", - ")\n", + "from mat3ra.made.tools.build.passivation.helpers import passivate_surface\n", + "from mat3ra.made.tools.enums import SurfaceTypesEnum\n", "\n", - "config = PassivationConfiguration(\n", - " slab=slab,\n", + "passivated_slab = passivate_surface(\n", + " slab,\n", " passivant=PASSIVANT,\n", " bond_length=BOND_LENGTH,\n", - " surface=SURFACE\n", - ")\n", - "\n", - "builder_params = SurfacePassivationBuilderParameters(\n", + " surface=SurfaceTypesEnum[SURFACE.upper()],\n", " shadowing_radius=SHADOWING_RADIUS,\n", " depth=DEPTH\n", ")\n", "\n", - "builder = SurfacePassivationBuilder(build_parameters=builder_params)" - ] - }, - { - "cell_type": "markdown", - "id": "2950f29de8bc79b2", - "metadata": { - "collapsed": false - }, - "source": [ - "### 2.2. Generate passivated structure\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a4ed473eb2129ac4", - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from mat3ra.made.tools.build.passivation import create_passivation\n", - "\n", - "passivated_slab = create_passivation(config, builder)\n", - "\n", "print(\"\\nPassivation completed:\")\n", "print(f\"Passivant used: {PASSIVANT}\")\n", "print(f\"Bond length: {BOND_LENGTH} Å\")\n", "print(f\"Surfaces passivated: {SURFACE}\")\n", "print(f\"Number of atoms: {len(passivated_slab.basis.elements.ids)}\")" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -258,17 +228,17 @@ }, { "cell_type": "code", - "execution_count": null, "id": "c4b5e1e0ec0ab02a", "metadata": { "collapsed": false }, - "outputs": [], "source": [ "print(\"Final passivated structure:\")\n", "visualize_materials(passivated_slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION)\n", "visualize_materials(passivated_slab, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION, rotation=\"-90x\")" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -282,17 +252,17 @@ }, { "cell_type": "code", - "execution_count": null, "id": "d66a15a29d27c6ea", "metadata": { "collapsed": false }, - "outputs": [], "source": [ "from utils.jupyterlite import set_materials\n", "\n", "set_materials(passivated_slab)" - ] + ], + "outputs": [], + "execution_count": null } ], "metadata": { diff --git a/pyproject.toml b/pyproject.toml index 1798bed2d..ea9863b98 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "matplotlib>=3.4.1", "pandas>=1.5.3", "pymatgen==2024.4.13", - "mat3ra-made>=2025.4.4.post0", + "mat3ra-made@git+https://github.com/Exabyte-io/made.git@ffeb01b29b7bf0ac62efb25c42c7612c9c2dee31", "mat3ra-utils>=2024.6.11.post0", ] diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py index 6abd9ee20..c39aa0a7e 100644 --- a/utils/jupyterlite.py +++ b/utils/jupyterlite.py @@ -129,6 +129,7 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Any]: List[Material]: A list of Material objects. """ from mat3ra.made.material import Material + from mat3ra.made.tools.build import MaterialWithBuildMetadata if globals_dict is None: # Get the globals of the caller for correct variable assignment during the execution of data_bridge extension @@ -142,7 +143,12 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Any]: get_data("materials_in", globals_dict) if "materials_in" in globals_dict and globals_dict["materials_in"]: - materials = [Material.create(item) for item in globals_dict["materials_in"]] + materials = [] + for item in globals_dict["materials_in"]: + try: + materials.append(MaterialWithBuildMetadata.create(item)) + except Exception: + materials.append(Material.create(item)) log(f"Retrieved {len(materials)} materials.") return materials else: diff --git a/utils/plot.py b/utils/plot.py index f102ada97..238ec608e 100644 --- a/utils/plot.py +++ b/utils/plot.py @@ -1,17 +1,17 @@ from typing import Dict, List, Union from mat3ra.made.material import Material +from mat3ra.made.tools.analyze.interface import ZSLMatchHolder from mat3ra.made.tools.analyze.rdf import RadialDistributionFunction -from mat3ra.made.tools.build.interface.enums import StrainModes from mat3ra.utils.jupyterlite.plot import plot_distribution_function, scatter_plot_2d -def plot_strain_vs_atoms(interfaces: List["Material"], settings: Dict[str, Union[str, int]]) -> None: +def plot_strain_vs_area(matches: List["ZSLMatchHolder"], settings: Dict[str, Union[str, int]]) -> None: """ Plot strain vs number of atoms for interfaces. Args: - interfaces: List of interfaces to plot. + matches: List of interface matches to plot. settings: Plot settings. """ @@ -20,18 +20,18 @@ def plot_strain_vs_atoms(interfaces: List["Material"], settings: Dict[str, Union hover_texts = [] trace_names = [] - for index, interface in enumerate(interfaces): - strain_percentage = interface.metadata[StrainModes.mean_abs_strain] * 100 - num_sites = len(interface.basis.coordinates.values) + for index, match in enumerate(matches): + strain_percentage = match.total_strain_percentage + match_area = match.match_area x_values.append(strain_percentage) - y_values.append(num_sites) - hover_texts.append(f"Index: {index}
Strain: {strain_percentage:.2f}%
Atoms: {num_sites}") + y_values.append(match_area) + hover_texts.append(f"Index: {index}
Strain: {strain_percentage:.2f}%
Area: {match_area:.2f} Ų") trace_names.append(f"Index: {index}") plot_settings = { "x_title": "Strain (%)", - "y_title": "Number of atoms", + "y_title": "Area (Ų)", "x_scale": settings["X_SCALE"], "y_scale": settings["Y_SCALE"], "height": settings["HEIGHT"],