Working in condensed matter physics, I (JerryI) often need to represent crystal structures based on their CIF, JSON, or other formats. Sometimes, it is quite tricky to parse these data files since you also need to determine the given symmetry operation when constructing a unit cell. Here, we will do it using AI Copilot π€
Uraniumβ
When I was measuring the spectrum of at the Nijmegen High-Magnetic-Field Lab during the morning shift, I had to make a short summary report and needed a nice plot of a unit cell.
GPT models can actually work with JSON data or Associations quite well. The first step is to get a CIF or JSON file on the crystal structure. This can be done using the Materials Project database. In the summary section, one can export a single JSON file and then import it into our notebook.
Import["UO2.json", "RawJSON"]
<|"@module"->"pymatgen.core.structure","@class"->"Structure","charge"->0,"lattice"-><|"matrix"->{{5.45401004`,0.`,3.339617969001764`*^-16},{8.770717076887777`*^-16,5.45401004`,3.339617969001764`*^-16},{0.`,0.`,5.45401004`}},"pbc"->{True,True,True},"a"->5.45401004`,"b"->5.45401004`,"c"->5.45401004`,"alpha"->90.`,"beta"->90.`,"gamma"->90.`,"volume"->162.23621261866322`|>,"properties"-><||>,"sites"->{<|"species"->{<|"element"->"U","oxidation_state"->4,"spin"->Null,"occu"->1|>},"abc"->{0.5`,0.`,0.`},"xyz"->{2.72700502`,0.`,1.669808984500882`*^-16},"properties"-><||>,"label"->"U4+"|>,<|"species"->{<|"element"->"U","oxidation_state"->4,"spin"->Null,"occu"->1|>},"abc"->{0.5`,0.5`,0.5`},"xyz"->{2.7270050200000004`,2.72700502`,2.7270050200000004`},"properties"-><||>,"label"->"U4+"|>,<|"species"->{<|"element"->"U","oxidation_state"->4,"spin"->Null,"occu"->1|>},"abc"->{0.`,0.`,0.5`},"xyz"->{0.`,0.`,2.72700502`},"properties"-><||>,"label"->"U4+"|>,<|"species"->{<|"element"->"U","oxidation_state"->4,"spin"->Null,"occu"->1|>},"abc"->{0.`,0.5`,0.`},"xyz"->{4.3853585384438886`*^-16,2.72700502`,1.669808984500882`*^-16},"properties"-><||>,"label"->"U4+"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.25`,0.75`,0.75`},"xyz"->{1.3635025100000007`,4.09050753`,4.09050753`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.25`,0.25`,0.75`},"xyz"->{1.3635025100000002`,1.36350251`,4.09050753`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.25`,0.25`,0.25`},"xyz"->{1.3635025100000002`,1.36350251`,1.3635025100000002`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.25`,0.75`,0.25`},"xyz"->{1.3635025100000007`,4.09050753`,1.3635025100000004`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.75`,0.75`,0.25`},"xyz"->{4.090507530000001`,4.09050753`,1.3635025100000004`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.75`,0.25`,0.25`},"xyz"->{4.09050753`,1.36350251`,1.3635025100000004`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.75`,0.25`,0.75`},"xyz"->{4.09050753`,1.36350251`,4.09050753`},"properties"-><||>,"label"->"O2-"|>,<|"species"->{<|"element"->"O","oxidation_state"->-2,"spin"->Null,"occu"->1|>},"abc"->{0.75`,0.75`,0.75`},"xyz"->{4.090507530000001`,4.09050753`,4.090507530000001`},"properties"-><||>,"label"->"O2-"|>}|>
It looks quite ugly. Let's ask our AI assistant to convert it to a 3D plot using following prompt
Ctrl/Cmd + P
and type
read crystal data in focused cell and draw a unit cell using 3D graphics and representing ions as spheres with different colors
The generated cell is following (using GPT-4o
model Jun 2024)
Module[{a = 5.45401004, unitCell, filledUnitCell},
unitCell = {
{Yellow, Sphere[{2.72700502, 0., 0.}, 0.5]},
{Yellow, Sphere[{2.72700502, 2.72700502, 2.72700502}, 0.5]},
{Yellow, Sphere[{0., 0., 2.72700502}, 0.5]},
{Yellow, Sphere[{0., 2.72700502, 0.}, 0.5]},
{Red, Sphere[{1.36350251, 4.09050753, 4.09050753}, 0.3]},
{Red, Sphere[{1.36350251, 1.36350251, 4.09050753}, 0.3]},
{Red, Sphere[{1.36350251, 1.36350251, 1.36350251}, 0.3]},
{Red, Sphere[{4.09050753, 1.36350251, 4.09050753}, 0.3]},
{Red, Sphere[{4.09050753, 4.09050753, 4.09050753}, 0.3]}
};
filledUnitCell = Flatten[Table[
Translate[unitCell, {i, j, k} a],
{i, 0, 1}, {j, 0, 1}, {k, 0, 1}
], 3];
Graphics3D[{filledUnitCell}]
]
One can also ask it to add borders
edit your cell and add borders of the unit cell using black lines
Module[{a = 5.45401004, unitCell, filledUnitCell, borders},
unitCell = {
{Yellow, Sphere[{2.72700502, 0., 0.}, 0.5]},
{Yellow, Sphere[{2.72700502, 2.72700502, 2.72700502}, 0.5]},
{Yellow, Sphere[{0., 0., 2.72700502}, 0.5]},
{Yellow, Sphere[{0., 2.72700502, 0.}, 0.5]},
{Red, Sphere[{1.36350251, 4.09050753, 4.09050753}, 0.3]},
{Red, Sphere[{1.36350251, 1.36350251, 4.09050753}, 0.3]},
{Red, Sphere[{1.36350251, 1.36350251, 1.36350251}, 0.3]},
{Red, Sphere[{4.09050753, 1.36350251, 4.09050753}, 0.3]},
{Red, Sphere[{4.09050753, 4.09050753, 4.09050753}, 0.3]}
};
filledUnitCell = Flatten[Table[
Translate[unitCell, {i, j, k} a],
{i, 0, 1}, {j, 0, 1}, {k, 0, 1}
], 3];
borders = {
Line[{{0, 0, 0}, {a, 0, 0}}],
Line[{{0, 0, 0}, {0, a, 0}}],
Line[{{0, 0, 0}, {0, 0, a}}],
Line[{{a, a, 0}, {0, a, 0}}],
Line[{{a, a, 0}, {a, 0, 0}}],
Line[{{a, 0, a}, {a, 0, 0}}],
Line[{{a, 0, a}, {0, 0, a}}],
Line[{{0, a, a}, {0, 0, a}}],
Line[{{0, a, a}, {0, a, 0}}],
Line[{{a, a, a}, {0, a, a}}],
Line[{{a, a, a}, {a, 0, a}}],
Line[{{a, a, a}, {a, a, 0}}]
};
Graphics3D[{filledUnitCell, Black, borders}]
]
This is amazing how modern LLM can read and parse any kind of data and convert them to the desired formats π¦