Skip to content

Commit 56f9806

Browse files
authored
Merge pull request #96 from Exabyte-io/feature/SOF-7232
Feature/SOF-7232
2 parents ba734ca + f7e2923 commit 56f9806

File tree

3 files changed

+837
-0
lines changed

3 files changed

+837
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Materials Transformations with Python Notebooks\n",
8+
"\n",
9+
"## Overview\n",
10+
"\n",
11+
"This Jupyter Lite distribution contains pre-configured examples of materials transformations including simple ones like creation of supercell or a surface, and more complex like creating an interface with Zur and McGill Superlattice matching algorithm\n",
12+
"\n",
13+
"## Examples\n",
14+
"\n",
15+
"### 1. Interface creation with Zur and McGill Superlattice algorithm\n",
16+
"\n",
17+
"[This file](zsl_interface_generation.ipynb) helps creating interface between two materials by finding matching superlattices and selecting optimal variants by size-strain trade-off. (Link to the lattice match algorithm: https://doi.org/10.1063/1.333084)\n",
18+
"\n",
19+
"### Definition for communication\n",
20+
"\n",
21+
"[definitions.py](definitions.py)\n"
22+
]
23+
},
24+
{
25+
"cell_type": "markdown",
26+
"metadata": {},
27+
"source": []
28+
}
29+
],
30+
"metadata": {
31+
"language_info": {
32+
"name": "python"
33+
}
34+
},
35+
"nbformat": 4,
36+
"nbformat_minor": 2
37+
}
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
from IPython.display import display, Javascript
2+
import json
3+
4+
5+
def set_materials(materials):
6+
"""
7+
This function takes a Python object, serializes it to JSON, and sends it to the host environment
8+
through a JavaScript function defined in the JupyterLite extension `data_bridge`.
9+
10+
Args:
11+
materials (object): The Python object to be sent to the host environment.
12+
"""
13+
python_data = materials
14+
serialized_data = json.dumps({"materials": python_data})
15+
js_code = f"""
16+
(function() {{
17+
window.sendDataToHost({serialized_data})
18+
console.log({serialized_data})
19+
}})();
20+
"""
21+
22+
display(Javascript(js_code))
23+
print("materials sent")
24+
25+
26+
def get_materials():
27+
"""
28+
This function requests materials from the host environment through a JavaScript function defined in the JupyterLite
29+
extension `data_bridge`. The materials are then returned to the Python environment.
30+
"""
31+
js_code = """
32+
(function() {
33+
if (window.requestDataFromHost) {
34+
window.requestDataFromHost();
35+
36+
} else {
37+
console.error('requestDataFromHost function is not defined on the window object.');
38+
}
39+
})();
40+
"""
41+
42+
display(Javascript(js_code))
43+
print("materials requested")
44+
45+
46+
from pymatgen.core import Structure, Lattice
47+
48+
49+
def to_pymatgen(material_data):
50+
"""
51+
Convert material object in ESSE format to a pymatgen Structure object.
52+
53+
Args:
54+
material_data (dict): A dictionary containing the material information in ESSE format.
55+
56+
Returns:
57+
Structure: A pymatgen Structure object.
58+
"""
59+
60+
# Extract lattice information
61+
lattice_params = material_data["lattice"]
62+
lattice_vectors = lattice_params["vectors"]
63+
a = lattice_vectors["a"]
64+
b = lattice_vectors["b"]
65+
c = lattice_vectors["c"]
66+
67+
# Create a Lattice
68+
lattice = Lattice([a, b, c])
69+
70+
# Extract the basis information
71+
basis = material_data["basis"]
72+
elements = [element["value"] for element in basis["elements"]]
73+
coordinates = [coord["value"] for coord in basis["coordinates"]]
74+
75+
# Assuming that the basis units are fractional since it's a crystal basis
76+
coords_are_cartesian = basis["units"].lower() != "crystal"
77+
78+
# Create the Structure
79+
structure = Structure(lattice, elements, coordinates, coords_are_cartesian=coords_are_cartesian)
80+
81+
return structure
82+
83+
84+
def from_pymatgen(structure: Structure):
85+
"""
86+
Convert a pymatgen Structure object to a material object in ESSE format.
87+
88+
Args:
89+
structure (Structure): A pymatgen Structure object.
90+
91+
Returns:
92+
dict: A dictionary containing the material information in ESSE format.
93+
"""
94+
basis = {
95+
"elements": [{"id": i, "value": str(site.specie)} for i, site in enumerate(structure.sites)],
96+
"coordinates": [{"id": i, "value": list(site.frac_coords)} for i, site in enumerate(structure.sites)],
97+
"units": "crystal",
98+
"cell": structure.lattice.matrix.tolist(),
99+
"constraints": [], # Assuming there are no constraints
100+
}
101+
102+
# Extract lattice information
103+
lattice = {
104+
"a": structure.lattice.a,
105+
"b": structure.lattice.b,
106+
"c": structure.lattice.c,
107+
"alpha": structure.lattice.alpha,
108+
"beta": structure.lattice.beta,
109+
"gamma": structure.lattice.gamma,
110+
"units": {"length": "angstrom", "angle": "degree"},
111+
"type": "FCC", # You need a way to determine the lattice type
112+
"vectors": {
113+
"a": structure.lattice.matrix[0].tolist(),
114+
"b": structure.lattice.matrix[1].tolist(),
115+
"c": structure.lattice.matrix[2].tolist(),
116+
"alat": 1, # This seems to be a scaling factor; adjust if necessary
117+
"units": "angstrom",
118+
},
119+
}
120+
121+
# Combine into a material dictionary
122+
material = {
123+
"name": structure.formula,
124+
"basis": basis,
125+
"lattice": lattice,
126+
"isNonPeriodic": not structure.is_ordered,
127+
"_id": "",
128+
"metadata": {"boundaryConditions": {"type": "bc2", "offset": 0}},
129+
"isUpdated": True,
130+
}
131+
132+
return material

0 commit comments

Comments
 (0)