Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5490529
feat: add NEB calculation notebook for QE neb.x
VsevolodX Jul 17, 2026
33de145
update: correct neb materials
VsevolodX Jul 20, 2026
956b2c7
update: generalize get by tag, by set
VsevolodX Jul 20, 2026
31f18aa
update: test generalize get by tag, by set
VsevolodX Jul 20, 2026
b0622ed
fix: drop api_client import so unit tests collect without [api]
VsevolodX Jul 20, 2026
6d6c1e9
update: create neb materials
VsevolodX Jul 21, 2026
4df9c9b
update: add helpers for material set
VsevolodX Jul 21, 2026
8dcd4ca
feat: NB to create materials with perturbations for neb
VsevolodX Jul 21, 2026
4e3833c
feat: NEB NB
VsevolodX Jul 21, 2026
414a297
update: helpers with material set
VsevolodX Jul 21, 2026
c587db0
update: reuse helper
VsevolodX Jul 21, 2026
85b31be
update: create materials set
VsevolodX Jul 21, 2026
730f296
fix: NEB materials-set lookup and job materialsSet wiring
VsevolodX Jul 21, 2026
acecc76
Merge origin/main into feature/SOF-7958
VsevolodX Aug 4, 2026
f49139c
rename: create_neb_images, utils_create_material_set (TB review)
VsevolodX Aug 4, 2026
958984e
fix: CodeRabbit advisories on the NEB path
VsevolodX Aug 4, 2026
e9a3f92
review: address tb-review findings on the NEB path
VsevolodX Aug 4, 2026
3a4c8a2
example: Si(100) surface, atom moved out of plane
VsevolodX Aug 4, 2026
5372435
rename: 'Create initial/final materials', moved to Perturbation 3D (TB)
VsevolodX Aug 4, 2026
e21d3c0
docs: lead create_neb_images generic, NEB as the example
VsevolodX Aug 4, 2026
7cc0b69
simplify: cut the materials-set helpers to what they do
VsevolodX Aug 4, 2026
5bb1b42
fix: fail clearly when no compute clusters are available
VsevolodX Aug 4, 2026
2a8c546
rename: create_initial_final_materials, drop noise prints
VsevolodX Aug 4, 2026
002bc7f
feat: translate_atoms helper, use it instead of a coordinate loop
VsevolodX Aug 4, 2026
b0e78e5
update: cleanup
VsevolodX Aug 4, 2026
85ecff1
revert: drop get_atom_indices_by_height and FROM_TOP
VsevolodX Aug 4, 2026
9f52c7a
update: adjust nb
VsevolodX Aug 4, 2026
fd64fdf
update: generalize
VsevolodX Aug 4, 2026
3b132e7
update: use made function
VsevolodX Aug 4, 2026
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
7 changes: 6 additions & 1 deletion other/materials_designer/Introduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"\n",
"### 5.1. 3D\n",
"#### [5.1.1. Maxwell-Boltzmann thermal disorder `X-3D-PER`](create_maxwell_disorder.ipynb)\n",
"#### [5.1.2. Create initial/final materials](create_initial_final_materials.ipynb). Transform a material into initial/intermediate/final images for a Nudged Elastic Band path.\n",
"\n",
"### 5.2. 2D\n",

@VsevolodX VsevolodX Aug 3, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Create initial/final materials" and move to "Perturbation 3D"


Reply via ReviewNB

"#### [5.2.1. Perturbation using sine wave `X-2D-PER`](create_perturbation.ipynb)\n",
Expand All @@ -97,6 +98,10 @@
"\n",
"This notebook demonstrates a workflow for converting materials data from the [JARVIS](https://jarvis.nist.gov/) database into ESSE format for use with the Mat3ra.com platform.\n",
"\n",
"### 6.2. Materials sets.\n",
"\n",
"#### [6.2.1. Create material set (ordered or unordered)](utils_create_material_set.ipynb). Save materials to a platform set for NEB, convex hull, EOS, etc.\n",
"\n",
"## 6.3. Development.\n",
"\n",
"#### [6.3.1. Custom Transformation](custom_transformation.ipynb). Notebook setup for development of custom transformations on materials.\n",
Expand All @@ -105,7 +110,7 @@
"\n",
"### 7.1. Under the hood.\n",
"\n",
"#### [7.1.1. More info about the conventions used](under_the_hood.ipynb)."
"#### [7.1.1. More info about the conventions used](under_the_hood.ipynb).\n"
]
},
{
Expand Down
273 changes: 273 additions & 0 deletions other/materials_designer/create_initial_final_materials.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
{

@timurbazhirov timurbazhirov Aug 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_neb_images


Reply via ReviewNB

@timurbazhirov timurbazhirov Aug 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use HfO2, ferroelectric switch - and use transformation matrix for the final structure generation


Reply via ReviewNB

"cells": [
{
"cell_type": "markdown",
"id": "0",
"metadata": {},
"source": [
"# Create Initial/Final Materials\n",
"\n",
"Build an ordered initial → (optional intermediates) → final set of materials from one starting structure, and write them to a subfolder under `uploads/` in path order for [`utils_create_material_set.ipynb`](utils_create_material_set.ipynb).\n",
"\n",
"Any calculation that takes an ordered start/end pair can use the output; a Nudged Elastic Band path ([`neb.ipynb`](workflows/neb.ipynb)) is one consumer.\n",
"\n",
"Order is preserved by **numbering material names** (`00_...`, `01_...`, …): `utils_create_material_set.ipynb` (and `load_materials_from_folder`) sort by filename, and filenames come from material names.\n",
"\n",
"## Usage\n",
"\n",
"1. Set the material and the names in cell 1.2.\n",
"1. Run 2.1, copy the coordinates of the atom you want to move, and paste them into 2.2.\n",
"1. Run the rest to build and write the path materials.\n",
"1. Open [`utils_create_material_set.ipynb`](utils_create_material_set.ipynb), set the same `SUBFOLDER_NAME` and `IS_ORDERED = True`, and run it to save the materials and create the platform set.\n",
"1. Use the printed set name as `MATERIAL_SET` in [`neb.ipynb`](workflows/neb.ipynb).\n",
"\n",
"## Summary\n",
"\n",
"1. Install packages and set parameters.\n",
"1. Load the starting material.\n",
"1. Clone it as the initial image; move one atom to make the final image.\n",
"1. Name members in path order and write them to `uploads/<SUBFOLDER_NAME>/`."
]
},
{
"cell_type": "markdown",
"id": "1",
"metadata": {},
"source": [
"## 1. Set up the environment and parameters\n",
"### 1.1. Install packages (JupyterLite)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.notebooks_utils.packages import install_packages\n",
"\n",
"await install_packages(\"made|api_examples\")\n"
]
},
{
"cell_type": "markdown",
"id": "3",
"metadata": {},
"source": [
"### 1.2. Set parameters\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4",
"metadata": {},
"outputs": [],
"source": [
"# Starting material (uploads folder or Standata name match)\n",
"FOLDER = \"uploads\"\n",
"MATERIAL_NAME = \"Silicon (100) surface\"\n",
"\n",
"# Short base name for the written images: 00_<PATH_NAME>.json, 01_<PATH_NAME>.json.\n",
"PATH_NAME = \"initial-final-materials\"\n",
"\n",
"# Subfolder under uploads/ to write path materials into — use the same value as\n",
"SUBFOLDER_NAME = \"initial_final_materials\""
]
},
{
"cell_type": "markdown",
"id": "5",
"metadata": {},
"source": [
"## 2. Build path materials\n",
"### 2.1. Load the starting material\n",
"\n",
"To read an atom's coordinates from the viewer below: open **Measurements** (the ruler icon), turn on\n",
"**Copy Coordinates [C]** — or press `C` — then click the atom. Its coordinates go to the clipboard,\n",
"ready to paste into 2.2."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.made.material import Material\n",
"from mat3ra.standata.materials import Materials\n",
"from mat3ra.notebooks_utils.ipython.entity.material.visualize import visualize_materials as visualize\n",
"from mat3ra.notebooks_utils.material import load_material_from_folder\n",
"\n",
"source_material = load_material_from_folder(FOLDER, MATERIAL_NAME) or Material.create(\n",
" Materials.get_by_name_first_match(MATERIAL_NAME)\n",
")\n",
"visualize(source_material, viewer=\"wave\")\n"
]
},
{
"cell_type": "markdown",
"id": "7",
"metadata": {},
"source": [
"### 2.2. Choose the atom to move\n",
"\n",
"`ATOM_COORDINATE` is the atom you copied above, in crystal coordinates; the nearest atom to it is the\n",
"one that moves.\n",
"\n",
"`TRANSLATION` is vector to move it, in Ångström."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8",
"metadata": {},
"outputs": [],
"source": [
"# Coordinates of the atom to move, copied from the viewer above.\n",
"ATOM_COORDINATE = [0.0, 0.5, 0.5633]\n",
"\n",
"# Displacement in Angstrom.\n",
"TRANSLATION = [0.0, 0.0, -2.0]"
]
},
{
"cell_type": "markdown",
"id": "9",
"metadata": {},
"source": [
"### 2.3. Clone as the initial image\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "10",
"metadata": {},
"outputs": [],
"source": [
"initial_material = source_material.clone()\n",
"visualize(initial_material, rotation=\"-90x\")\n"
]
},
{
"cell_type": "markdown",
"id": "11",
"metadata": {},
"source": [
"### 2.4. Transform into the final image (example)\n",
"\n",
"Default: move the atom at `ATOM_COORDINATE` by `TRANSLATION`. Replace with any other transformation (defects, swaps, custom coordinates, …).\n",
"\n",
"2.5 below shows the same move done as a displacement *field* instead, which is what you want when the neighbours should relax along with the atom.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "12",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.made.tools.analyze.other import get_closest_site_id_from_coordinate\n",
"from mat3ra.made.tools.operations.core.unary import translate_atoms\n",
"\n",
"atom_id = get_closest_site_id_from_coordinate(initial_material, ATOM_COORDINATE)\n",
"final_material = translate_atoms(initial_material, [atom_id], TRANSLATION)\n",
"\n",
"visualize([initial_material, final_material], viewer=\"wave\")"
]
},
{
"cell_type": "markdown",
"id": "13",
"metadata": {},
"source": [
"### 2.5. Alternative: move the atom with a perturbation function (example)\n",
"\n",
"`translate_atoms` above applies a fixed vector. A perturbation function instead returns `∆z` for\n",
"*every* atom from `f(x, y, z)`, so a Gaussian centred on one atom keeps the displacement local to\n",
"it — and lets the path be shaped (neighbours relaxing along with it, a wave, a decaying tail)\n",
"rather than a rigid shift.\n",
"\n",
"Left commented out so \"Run All\" uses the simple translation. Uncomment it to overwrite\n",
"`final_material`, run, and compare the two structures in the viewer."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "14",
"metadata": {},
"outputs": [],
"source": [
"# import numpy as np\n",
"# import sympy as sp\n",
"# from mat3ra.made.tools.build_components.operations.core.modifications.perturb import FunctionHolder\n",
"# from mat3ra.made.tools.operations.core.unary import perturb\n",
"#\n",
"# SIGMA = 0.5 # Angstrom — how tightly the displacement is localised around the atom\n",
"#\n",
"# center_x, center_y, center_z = np.array(ATOM_COORDINATE) @ np.array(\n",
"# initial_material.lattice.vector_arrays\n",
"# )\n",
"#\n",
"# x, y, z = sp.symbols(\"x y z\")\n",
"# displacement_function = TRANSLATION[2] * sp.exp(\n",
"# -(((x - center_x) ** 2 + (y - center_y) ** 2 + (z - center_z) ** 2) / (2 * SIGMA**2))\n",
"# )\n",
"#\n",
"# final_material = perturb(\n",
"# initial_material,\n",
"# FunctionHolder(function=displacement_function),\n",
"# use_cartesian_coordinates=True,\n",
"# )\n",
"# visualize([initial_material, final_material], viewer=\"wave\")"
]
},
{
"cell_type": "markdown",
"id": "15",
"metadata": {},
"source": [
"### 2.6. Name members in path order and write to the subfolder\n",
"\n",
"Numeric prefixes control load order in `utils_create_material_set.ipynb` (filenames are sorted; filenames come from material names).\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "16",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.notebooks_utils.material import set_materials\n",
"from mat3ra.notebooks_utils.settings import UPLOADS_FOLDER\n",
"\n",
"path_materials = [initial_material, final_material]\n",
"for index, material in enumerate(path_materials):\n",
" material.name = f\"{index:02d}_{PATH_NAME}\"\n",
"\n",
"subfolder_path = f\"{UPLOADS_FOLDER}/{SUBFOLDER_NAME}\"\n",
"set_materials(path_materials, folder_path=subfolder_path)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading
Loading