-
Notifications
You must be signed in to change notification settings - Fork 15
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
Upgrade the aimsgb structure factory #1123
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,10 @@ | |
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department | ||
# Distributed under the terms of "New BSD License", see the LICENSE file. | ||
|
||
from structuretoolkit.build import grainboundary, get_grainboundary_info | ||
from pyiron_atomistics.atomistics.structure.atoms import ase_to_pyiron | ||
from pyiron.atomistics.structure.atoms import pyiron_to_pymatgen, pymatgen_to_pyiron | ||
from pymatgen.io.ase import AseAtomsAdaptor | ||
from aimsgb import GBInformation, GrainBoundary, Grain | ||
|
||
|
||
__author__ = "Ujjal Saikia" | ||
__copyright__ = ( | ||
|
@@ -19,75 +21,105 @@ | |
|
||
class AimsgbFactory: | ||
@staticmethod | ||
def info(axis, max_sigma): | ||
def info(axis, | ||
max_sigma=15, | ||
specific=False, | ||
table_view=False | ||
): | ||
""" | ||
Provides a list of possible GB structures for a given rotational axis and upto the given maximum sigma value. | ||
|
||
A dictionary with information including possible sigma, CSL matrix, GB plane, | ||
rotation angle and rotation matrix. | ||
Args: | ||
axis : Rotational axis for the GB you want to construct (for example, axis=[1,0,0]) | ||
max_sigma (int) : The maximum value of sigma upto which you want to consider for your | ||
GB (for example, sigma=5) | ||
axis ([u, v, w]): Rotation axis. | ||
max_sigma (int): The largest sigma value. Dafult value is 15. | ||
specific (bool): Whether collecting information for a specific sigma. | ||
Dafult value is False. | ||
table_view (bool): Display output in a tabuler format. Default value is True. | ||
|
||
Returns: | ||
A list of possible GB structures in the format: | ||
A aimsgb.GBInformation object or display a table depending on | ||
the value of table_view parameter. | ||
|
||
{sigma value: {'theta': [theta value], | ||
'plane': the GB planes") | ||
'rot_matrix': array([the rotational matrix]), | ||
'csl': [array([the csl matrix])]}} | ||
|
||
To construct the grain boundary select a GB plane and sigma value from the list and pass it to the | ||
GBBuilder.gb_build() function along with the rotational axis and initial bulk structure. | ||
To construct the grain boundary select a GB plane and sigma value from | ||
the table and pass it to the GBBuilder.build() function along with | ||
the rotational axis and initial bulk structure. | ||
""" | ||
return get_grainboundary_info(axis=axis, max_sigma=max_sigma) | ||
if table_view: | ||
return print(GBInformation(axis, max_sigma, specific).__str__()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @liamhuber Thanks a lot for the feedback. I will implement the changes you suggested. |
||
else: | ||
return GBInformation(axis, max_sigma, specific) | ||
|
||
@staticmethod | ||
def build( | ||
axis, | ||
sigma, | ||
plane, | ||
initial_struct, | ||
to_primitive=False, | ||
delete_layer="0b0t0b0t", | ||
add_if_dist=0.0, | ||
uc_a=1, | ||
uc_b=1, | ||
): | ||
def build(axis, | ||
sigma, | ||
plane, | ||
initial_struct, | ||
uc_a=1, | ||
uc_b=1, | ||
vacuum=0.0, | ||
gap=0.0, | ||
delete_layer='0b0t0b0t', | ||
tol=0.25, | ||
to_primitive=False | ||
): | ||
""" | ||
Generate a grain boundary structure based on the aimsgb.GrainBoundary module. | ||
A grain boundary (GB) object. The initial structure can be cubic or non-cubic | ||
crystal. If non-cubic, the crystal will be transferred to conventional cell. | ||
The generated GB could be either tilted or twisted based on the given GB | ||
plane. If the GB plane is parallel to the rotation axis, the generated GB | ||
will be a twisted one. Otherwise, tilted. Build grain boundary based on | ||
rotation axis, sigma, GB plane, grain size, initial_struct and vacuum thickness. | ||
Build an interface structure by stacking two grains along a given direction. | ||
The grain_b a- and b-vectors will be forced to be the grain_a's a- and b-vectors. | ||
|
||
Args: | ||
axis : Rotational axis for the GB you want to construct (for example, axis=[1,0,0]) | ||
sigma (int) : The sigma value of the GB you want to construct (for example, sigma=5) | ||
plane: The grain boundary plane of the GB you want to construct (for example, plane=[2,1,0]) | ||
initial_struct : Initial bulk structure from which you want to construct the GB (a pyiron | ||
structure object). | ||
delete_layer : To delete layers of the GB. For example, delete_layer='1b0t1b0t'. The first | ||
4 characters is for first grain and the other 4 is for second grain. b means | ||
bottom layer and t means top layer. Integer represents the number of layers | ||
to be deleted. The first t and second b from the left hand side represents | ||
the layers at the GB interface. Default value is delete_layer='0b0t0b0t', which | ||
means no deletion of layers. | ||
add_if_dist : If you want to add extra interface distance, you can specify add_if_dist. | ||
Default value is add_if_dist=0.0 | ||
to_primitive : To generate primitive or non-primitive GB structure. Default value is | ||
to_primitive=False | ||
axis ([u, v, w]): Rotation axis. | ||
sigma (int): The area ratio between the unit cell of CSL and the | ||
given crystal lattice. | ||
plane ([h, k, l]): Miller index of GB plane. If the GB plane is parallel | ||
to the rotation axis, the generated GB will be a twist GB. If they | ||
are perpendicular, the generated GB will be a tilt GB. | ||
initial_struct (Grain): Initial input structure. Must be an object of | ||
pyiron_atomistics.atomistics.structure.atoms.Atoms | ||
uc_a (int): Number of unit cell of grain A. Default to 1. | ||
uc_b (int): Number of unit cell of grain B. Default to 1. | ||
vacuum (float): Vacuum space between the surface of the grains in Angstroms. Default to 0.0 | ||
gap (float): Gap between the GB interface of the grains in Angstroms. Default to 0.0 | ||
delete_layer (str): Delete top and bottom layers of the first and the second grains. | ||
8 characters in total. The first 4 characters is for the first grain and | ||
the other 4 is for the second grain. "b" means bottom layer and "t" means | ||
top layer. Integer represents the number of layers to be deleted. | ||
Default to "0b0t0b0t", which means no deletion of layers. The | ||
direction of top and bottom layers is based on the given direction. | ||
tol (float): Tolerance factor in Angstrom to determnine if sites are | ||
in the same layer. Default to 0.25. | ||
to_primitive (bool): Whether to get primitive structure of GB. Default to False. | ||
|
||
|
||
Returns: | ||
:class:`.Atoms`: final grain boundary structure | ||
""" | ||
return ase_to_pyiron( | ||
grainboundary( | ||
axis=axis, | ||
sigma=sigma, | ||
plane=plane, | ||
initial_struct=initial_struct, | ||
to_primitive=to_primitive, | ||
delete_layer=delete_layer, | ||
add_if_dist=add_if_dist, | ||
uc_a=uc_a, | ||
uc_b=uc_b, | ||
) | ||
) | ||
basis_pmg = AseAtomsAdaptor.get_structure(initial_struct) | ||
|
||
basis_pmg = Grain(lattice=basis_pmg.lattice, | ||
species=basis_pmg.species, | ||
coords=basis_pmg.frac_coords) | ||
|
||
gb = GrainBoundary(axis=axis, | ||
sigma=sigma, | ||
plane=plane, | ||
initial_struct=basis_pmg, | ||
uc_a=uc_a, | ||
uc_b=uc_b) | ||
|
||
structure = Grain.stack_grains(grain_a=gb.grain_a, | ||
grain_b=gb.grain_b, | ||
vacuum=vacuum, | ||
gap=gap, | ||
direction=gb.direction, | ||
delete_layer=delete_layer, | ||
tol=tol, | ||
to_primitive=to_primitive) | ||
|
||
return pymatgen_to_pyiron(structure) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the structure toolkit interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interface is pretty similar and this is what is used by
pyiron_atomistics
in the background https://github.com/pyiron/structuretoolkit/blob/main/structuretoolkit/build/aimsgb.pyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened a jupyter notebook from the jupyterhub session runnig at cmti and tried to import
from structuretoolkit.common.pymatgen import ase_to_pymatgen, pymatgen_to_ase
and got this errorModuleNotFoundError: No module named 'structuretoolkit.common'
from structuretoolkit.build import grainboundary, get_grainboundary_info
also gave me the errorImportError: cannot import name 'grainboundary' from 'structuretoolkit.build' (/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.10/site-packages/structuretoolkit/build/__init__.py)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I got this. I have to modify the import statement from
from structuretoolkit.build import grainboundary, get_grainboundary_info
tofrom structuretoolkit.build.aimsgb import grainboundary_info, grainboundary_build
But, still can't figure out what is the new alternative of
structuretoolkit.common.pymatgen import ase_to_pymatgen, pymatgen_to_ase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I am confused, because it is available in the official package https://github.com/pyiron/structuretoolkit/blob/main/structuretoolkit/common/pymatgen.py . Which version of structure toolkit is installed on cmti? You can check the version using
conda list structuretoolkit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output of
conda list structuretoolkit
is as follows:packages in environment at /u/system/SLES12/soft/pyiron/dev/anaconda3:
Name Version Build Channel
structuretoolkit 0.0.1 pyhd8ed1ab_1 conda-forge
Note: you may need to restart the kernel to use updated packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this is a rather old version - the current version is
0.0.7
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jan-janssen Thanks! I noticed that the current incompatibility issue is coming from this line
AseAtomsAdaptor.get_structure(initial_struct, cls=None)
. The optioncls=None
is no longer accepted. We can change it toAseAtomsAdaptor.get_structure(initial_struct)
which will take the default value which ispymatgen.Structure