Skip to content

other/shapes #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
313 changes: 313 additions & 0 deletions other/materials_designer/create_cutout_heart_shape.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
{
"cells": [
{
"cell_type": "markdown",
"source": [
"# Create a heart-shape cutout\n",
"\n",
"Create a slab with a complex cutout pattern.\n",
"By default, this notebook generates a structure of etching pattern:\n",
"- Two vertical side walls\n",
"- Two parallel channels at the top\n",
"- A deeper central cavity\n",
"\n",
"<h2 style=\"color:green\">Usage</h2>\n",
"\n",
"1. Make sure to select Input Material (in the outer runtime) before running the notebook.\n",
"2. Set structural parameters in cell 1.2 below\n",
"4. Click \"Run\" > \"Run All\" to create the structure\n",
"5. Scroll down to view the resulting structure from multiple angles\n",
"\n",
"## Resulting structure:\n",
"<img src=\"https://i.imgur.com/j9YDJ1X.png\">"
],
"metadata": {
"collapsed": false
},
"id": "f2e1e795020d7b3f"
},
{
"cell_type": "markdown",
"source": [
"## 1. Prepare the Environment\n",
"### 1.1. Install Packages\n",
"The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb))."
],
"metadata": {
"collapsed": false
},
"id": "98aa134f51746218"
},
{
"cell_type": "code",
"source": [
"import sys\n",
"\n",
"if sys.platform == \"emscripten\":\n",
" import micropip\n",
"\n",
" await micropip.install('mat3ra-api-examples', deps=False)\n",
" from utils.jupyterlite import install_packages\n",
"\n",
" await install_packages(\"\")"
],
"metadata": {
"collapsed": false
},
"id": "280f9794a876678b",
"outputs": [],
"execution_count": null
},
{
"metadata": {},
"cell_type": "markdown",
"source": "### 1.2. Set up structure parameters",
"id": "b3d4d3ea7b589f89"
},
{
"metadata": {
"collapsed": false
},
"cell_type": "code",
"source": [
"# Slab parameters\n",
"MILLER_INDICES = (0, 0, 1)\n",
"THICKNESS = 10 # unit cell layers\n",
"VACUUM = 6.0 # Angstrom\n",
"XY_SUPERCELL_MATRIX = [[10, 0], [0, 10]]\n",
"\n",
"# Heart shape parameters in crystal units\n",
"HEART_WIDTH = 0.75 # Width of heart relative to cell\n",
"HEART_HEIGHT = 0.8 # Height of heart relative to cell\n",
"NAME = \"Diamond Heart Y-taper - C\""
],
"id": "5177e239254e3601",
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"### 1.3. Create a condition on coordinates\n"
],
"metadata": {
"collapsed": false
},
"id": "361c291aaf3feb2a"
},
{
"cell_type": "code",
"source": [
"\n",
"\n",
"from typing import List\n",
"from mat3ra.made.tools.utils.coordinate import CoordinateCondition\n",
"\n",
"class YTaperedHeartShapeCondition(CoordinateCondition):\n",
" \"\"\"\n",
" Defines a heart-shaped structure with y-direction tapering applied.\n",
" All dimensions are specified as fractions of the total size (0.0 to 1.0).\n",
" \"\"\"\n",
" width: float = 0.75 # Heart width relative to cell size\n",
" height: float = 0.8 # Heart height relative to cell size\n",
" max_thickness: float = 0.4 # Maximum thickness (y-direction) at the top\n",
"\n",
" def condition(self, coordinate: List[float]) -> bool:\n",
" \"\"\"\n",
" Returns True for positions that should be removed.\n",
" Creates a heart shape with y-direction tapering.\n",
" \"\"\"\n",
" x, y, z = coordinate\n",
"\n",
" # Center and scale coordinates\n",
" x = (x - 0.5) * 2 / self.width\n",
" y = (y - 0.5) * 2 / self.width\n",
" z = (z - 0.5) * 2 / self.height\n",
"\n",
" # Heart shape equation (in xz-plane)\n",
" heart_equation = (x**2 + z**2 - 1)**3 - x**2 * z**3\n",
" in_heart = heart_equation <= 0 # True if within heart shape\n",
"\n",
" # Apply tapering: dynamically reduce thickness in the y-direction\n",
" taper_factor = 1 - max(0, -z * 0.7) # Adjust tapering intensity\n",
" dynamic_thickness = self.max_thickness * taper_factor\n",
"\n",
" in_thickness = abs(y) <= dynamic_thickness # Adjust thickness dynamically\n",
"\n",
" # Return True to remove atoms OUTSIDE the heart shape\n",
" return not (in_heart and in_thickness)\n",
"\n",
"# Create the condition\n",
"condition = YTaperedHeartShapeCondition(\n",
" width=HEART_WIDTH,\n",
" height=HEART_HEIGHT,\n",
" max_thickness=0.4 # Adjustable max thickness\n",
").condition\n"
],
"metadata": {
"collapsed": false
},
"id": "56c8227695643174",
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"### 1.3. Get input materials"
],
"metadata": {
"collapsed": false
},
"id": "91724db55eddad60"
},
{
"cell_type": "code",
"source": [
"from utils.jupyterlite import get_materials\n",
"\n",
"materials = get_materials(globals())\n",
"material = materials[0]"
],
"metadata": {
"collapsed": false
},
"id": "ceebf2a5229da67c",
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"### 1.4. Preview the material"
],
"metadata": {
"collapsed": false
},
"id": "13964644436b4156"
},
{
"cell_type": "code",
"source": [
"from utils.visualize import visualize_materials as visualize\n",
"\n",
"visualize(material, repetitions=[1, 1, 1], rotation=\"0x\")\n",
"visualize(material, repetitions=[1, 1, 1], rotation=\"-90x\")"
],
"metadata": {
"collapsed": false
},
"id": "45f0c424ece00186",
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"## 2. Create target material\n",
"### 2.1. Create a slab and apply the cutout condition"
],
"metadata": {
"collapsed": false
},
"id": "615800437b2ef7a"
},
{
"cell_type": "code",
"source": [
"from mat3ra.made.tools.modify import filter_by_condition_on_coordinates, add_vacuum\n",
"from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n",
"\n",
"slab_config = SlabConfiguration(\n",
" bulk=material,\n",
" miller_indices=MILLER_INDICES,\n",
" thickness=THICKNESS,\n",
" vacuum=0,\n",
" xy_supercell_matrix=XY_SUPERCELL_MATRIX,\n",
" use_orthogonal_z=True,\n",
" use_conventional_cell=True,\n",
")\n",
"\n",
"slab_unit_cell = create_slab(slab_config)\n",
"resulting_material = filter_by_condition_on_coordinates(slab_unit_cell, condition, invert_selection=True)\n",
"resulting_material = add_vacuum(resulting_material, VACUUM)"
],
"metadata": {
"collapsed": false
},
"id": "422815d29aa347a1",
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"## 3. Visualize the result"
],
"metadata": {
"collapsed": false
},
"id": "57cc38ec0df3c1f7"
},
{
"cell_type": "code",
"source": [
"visualize(resulting_material, repetitions=[1, 1, 1], rotation=\"0x\")\n",
"visualize(resulting_material, repetitions=[1, 1, 1], rotation=\"-90x\")\n",
"visualize(resulting_material, repetitions=[1, 1, 1], rotation=\"-90x,-90y\")"
],
"metadata": {
"collapsed": false
},
"id": "2a9627cd4a261067",
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"# 4. Pass material to the outside runtime"
],
"metadata": {
"collapsed": false
},
"id": "c67e6f5363e80942"
},
{
"cell_type": "code",
"source": [
"from utils.jupyterlite import set_materials\n",
"\n",
"resulting_material.name = NAME\n",
"set_materials(resulting_material)"
],
"metadata": {
"collapsed": false
},
"id": "cbee60d4b936e5cb",
"outputs": [],
"execution_count": null
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}