Skip to content

API

alff

ALFF: Frameworks for Active Learning of Graph-based Force Fields and Computation of Material Properties.

Developed and maintained by C.Thang Nguyen

Modules:

Attributes:

ALFF_ROOT = Path(__file__).parent module-attribute

__author__ = 'C.Thang Nguyen' module-attribute

__contact__ = 'http://thangckt.github.io/email' module-attribute

_version

Attributes:

__all__ = ['__version__', '__version_tuple__', 'version', 'version_tuple', '__commit_id__', 'commit_id'] module-attribute

TYPE_CHECKING = False module-attribute

VERSION_TUPLE = Tuple[Union[int, str], ...] module-attribute

COMMIT_ID = Union[str, None] module-attribute

version: str = '0.1.1.dev1' module-attribute

__version__: str = '0.1.1.dev1' module-attribute

__version_tuple__: VERSION_TUPLE = (0, 1, 1, 'dev1') module-attribute

version_tuple: VERSION_TUPLE = (0, 1, 1, 'dev1') module-attribute

commit_id: COMMIT_ID = 'g53590e81d' module-attribute

__commit_id__: COMMIT_ID = 'g53590e81d' module-attribute

al

Modules:

active_learning

Classes:

Functions:

WorkflowActiveLearning(param_file: str, machine_file: str)

Bases: Workflow

Workflow for active learning. Note: Need to redefine .run() method, since the Active Learning workflow is different from the base class.

Methods:

Attributes:

stage_map = {'ml_train': stage_train, 'md_explore': stage_md, 'dft_label': stage_dft} instance-attribute
wf_name = 'ACTIVE LEARNING' instance-attribute
param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
stage_list = self._load_stage_list() instance-attribute
run()
_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()
stage_train(iter_idx, pdict, mdict)

This function does: - collect data files - prepare training args based on MLP engine

stage_md(iter_idx, pdict, mdict)

New stage function for MD tasks, including: pre, run, post MD. - Collect initial configurations - Prepare MD args - Submit MD jobs to remote machines - Postprocess MD results

stage_dft(iter_idx, pdict, mdict)

New stage function for DFT tasks, including: pre, run, post DFT.

_collect_dft_label_data(structure_dirs, data_outdir)

Collect DFT labeled data from structure_dirs to file work_dir/DIR_DATA/FILE_ITER_DATA.

Parameters:

  • structure_dirs (list) –

    List of structure directories to collect data from.

  • data_outdir (str) –

    The working directory to store collected data.

Raises:

  • RuntimeError

    If no data is generated in this iteration.

_get_engines(pdict) -> tuple[str]
_check_work_dir(work_dir)
write_iterlog(iter_idx: int, stage_idx: int, stage_name: str, last_iter: bool = True) -> None

Write the current iteration and stage to the iter log file. If last_iter is True, only the last iteration is saved.

read_iterlog() -> list[int]

Read the last line of the iter log file.

iter_str(iter_idx: int) -> str
breakline_iter(iter_idx: int) -> str
breakline_stage(iter_idx: int, stage_idx: int, stage_name: str) -> str

finetune

Classes:

  • WorkflowFinetune

    Workflow for fine-tuning the existed ML models or train a new ML model.

Functions:

WorkflowFinetune(param_file: str, machine_file: str)

Bases: Workflow

Workflow for fine-tuning the existed ML models or train a new ML model. Needs to override self.stage_list in base class, because the stages are fixed here.

Methods:

  • run

    The main function to run the workflow. This default implementation works for simple workflow,

Attributes:

stage_map = {'training': stage_train} instance-attribute
wf_name = 'FINE-TUNING' instance-attribute
stage_list = ['training'] instance-attribute
param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
run()

The main function to run the workflow. This default implementation works for simple workflow, for more complex workflow (e.g. with iteration like active learning), need to reimplement this .run() function.

_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()
stage_train(pdict, mdict)

This function does: - collect data files - prepare training args based on MLP engine

libal_md_ase

Classes:

Functions:

OperAlmdAseSevennet(work_dir, pdict, multi_mdict, mdict_prefix='md')

Bases: RemoteOperation

This class runs ASE md for a list of structures in task_dirs.

Methods:

Attributes:

op_name = 'ASE md' instance-attribute
has_files = ['conf.lmpdata'] instance-attribute
no_files = ['committee_error.txt'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare the task_list - Prepare fordward & backward files - Prepare commandlist_list for multi-remote submission

postprocess()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

premd_ase_sevenn(work_dir, pdict, mdict)

This function does: - prepare MD args - generate task_dirs for ranges of temperature and press

temperature_press_mdarg_ase(struct_dirs: list, temperature_list: list = [], press_list: list = [], ase_argdict: dict = {}) -> list

Generate the task_dirs for ranges of temperatures and stresses.

Parameters:

  • struct_dirs (list) –

    List of dirs contains configuration files.

  • temperature_list (list, default: [] ) –

    List of temperatures.

  • press_list (list, default: [] ) –

    List of stresses.

  • ase_argdict (dict, default: {} ) –

libal_md_lammps

Classes:

Functions:

OperAlmdLammpsSevennet(work_dir, pdict, multi_mdict, mdict_prefix='md')

Bases: RemoteOperation

This class runs LAMMPS md for a list of structures in task_dirs.

Methods:

Attributes:

op_name = 'LAMMPS md' instance-attribute
has_files = ['conf.lmpdata'] instance-attribute
no_files = ['committee_error.txt'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare the task_list - Prepare fordward & backward files - Prepare commandlist_list for multi-remote submission

postprocess()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

premd_lammps_sevenn(work_dir, pdict, mdict)

This function does: - prepare MD args - generate task_dirs for ranges of temperature and press

_check_sampling_enough(file: str) -> bool

Check if the sampling result is sastified. Args: file (str): The text file summarizing the sampling result. Returns: bool: True if the sampling result is sastified, False otherwise.

temperature_press_mdarg_lammps(struct_dirs: list, temperature_list: list = [], press_list: list = [], lammps_argdict: dict = {}) -> list

Generate the task_dirs for ranges of temperatures and stresses.

Parameters:

  • struct_dirs (list) –

    List of dirs contains configuration files.

  • temperature_list (list, default: [] ) –

    List of temperatures.

  • press_list (list, default: [] ) –

    List of stresses.

  • lammps_argdict (dict, default: {} ) –

utilal_uncertainty

DO NOT use any alff imports in this file, since it will be used remotely.

Functions:

  • committee_err_energy

    Committee error for energy on a single configuration

  • committee_err_force

    Committee error for forces on a single configuration

  • committee_err_stress

    Committee error for stress on a single configuration

  • committee_error

    Calculate committee error for energy, forces and stress for a list of configurations

  • committee_judge

    Decide whether an configuration is candidate, accurate, or inaccurate based on committee error

  • select_candidate

    Select candidate configurations for DFT calculation

  • remove_inaccurate

    Remove inaccurate configurations based on committee error. This is used to revise the dataset.

  • select_candidate_SevenNet

    Select candidate configurations for DFT calculation using SevenNet models.

  • remove_inaccurate_SevenNet

    Remove inaccurate configurations based on committee error, using SevenNet models.

  • simple_lmpdump2extxyz

    Convert LAMMPS dump file to extended xyz file. This is very simple version, only convert atomic positions, but not stress tensor.

_assign_calc(struct: Atoms, calc: object) -> Atoms

helper to assign calculator to an Atoms object. Why need this? - Avoids modifying the original Atoms object. - Avoids return 'NoneType' when directly call '.set_calculator(calc)' in list comprehension.

committee_err_energy(struct: Atoms, calc_list: list[Calculator]) -> float

Committee error for energy on a single configuration

Parameters:

  • struct (Atoms) –

    Atoms object

  • calc_list (list[Calculator]) –

    list of ASE's calculators of ML models in the committee.

Returns:

  • e_std ( float ) –

    standard deviation of the energy

committee_err_force(struct: Atoms, calc_list: list[Calculator], rel_force: float = None) -> tuple[float, float, float]

Committee error for forces on a single configuration

Parameters:

  • struct (Atoms) –

    Atoms object

  • calc_list (list[Calculator]) –

    list of ASE's calculators of ML models in the committee.

  • rel_force (float, default: None ) –

    relative force. Defaults to None.

Returns:

  • f_std_mean ( float ) –

    mean of the standard deviation of atomic forces in the configuration

  • f_std_max ( float ) –

    maximum of the standard deviation

  • f_std_min ( float ) –

    minimum of the standard deviation

committee_err_stress(struct: Atoms, calc_list: list[Calculator], rel_stress: float = None) -> tuple[float, float, float]

Committee error for stress on a single configuration

Parameters:

  • struct (Atoms) –

    Atoms object

  • calc_list (list[Calculator]) –

    list of ASE's calculators of ML models in the committee.

  • rel_stress (float, default: None ) –

    relative stress. Defaults to None.

Returns:

  • s_std_mean ( float ) –

    mean of the standard deviation of the stress in the configuration

  • s_std_max ( float ) –

    maximum of the standard deviation

  • s_std_min ( float ) –

    minimum of the standard deviation

committee_error(extxyz_file: str, calc_list: list[Calculator], rel_force: float = None, compute_stress: bool = True, rel_stress: float = None, outfile: str = 'committee_error.txt')

Calculate committee error for energy, forces and stress for a list of configurations

Parameters:

  • extxyz_file (str) –

    extended xyz file containing multiples configurations

  • calc_list (list[Calculator]) –

    list of ASE's calculators of ML models

  • rel_force (float, default: None ) –

    relative force. Defaults to None.

  • compute_stress (bool, default: True ) –

    whether to compute stress. Defaults to True.

  • rel_stress (float, default: None ) –

    relative stress. Defaults to None.

  • outfile (str, default: 'committee_error.txt' ) –

    output file. Defaults to "committee_error.txt".

Returns:

  • outfile ( str ) –

    "committee_error.txt" with the following columns: "e_std f_std_mean f_std_max f_std_min s_std_mean s_std_max s_std_min"

committee_judge(committee_error_file: str, e_std_hi: float = 0.1, e_std_lo: float = 0.0, f_std_hi: float = 0.1, f_std_lo: float = 0.0, s_std_hi: float = None, s_std_lo: float = 0.0) -> tuple[np.ndarray, np.ndarray, np.ndarray]

Decide whether an configuration is candidate, accurate, or inaccurate based on committee error

Parameters:

  • committee_error_file (str) –

    committee error file

  • e_std_hi (float, default: 0.1 ) –

    energy std high. Defaults to 0.1.

  • e_std_lo (float, default: 0.0 ) –

    energy std low. Defaults to 0.05.

  • f_std_hi (float, default: 0.1 ) –

    force std high. Defaults to 0.1.

  • f_std_lo (float, default: 0.0 ) –

    force std low. Defaults to 0.05.

  • s_std_hi (float, default: None ) –

    stress std high. Defaults to 0.1.

  • s_std_lo (float, default: 0.0 ) –

    stress std low. Defaults to 0.05.

Returns:

  • committee_error_file ( s ) –

    files contain candidate, accurate and inaccurate configurations

Note
  • If need to select candidates based on only energy, just set f_std_lo and s_std_lo to a very large values. By this way, the criterion for those terms will never meet.
  • Similarly, if need to select candidates based on only energy and force, set s_std_lo to a very large value. E.g., s_std_lo=1e6 for selecting candidates based on energy and force.
select_candidate(extxyz_file: str, calc_list: list[Calculator], rel_force: float = None, compute_stress: bool = True, rel_stress: float = None, e_std_hi: float = 0.1, e_std_lo: float = 0.0, f_std_hi: float = 0.1, f_std_lo: float = 0.0, s_std_hi: float = None, s_std_lo: float = 0.0)

Select candidate configurations for DFT calculation

Returns:

  • extxyz_file ( str ) –

    candidate configurations

Note: See parameters in functions committee_error and committee_judge.

remove_inaccurate(extxyz_file: str, calc_list: list[Calculator], rel_force: float = None, compute_stress: bool = True, rel_stress: float = None, e_std_hi: float = 0.1, e_std_lo: float = 0.0, f_std_hi: float = 0.1, f_std_lo: float = 0.0, s_std_hi: float = None, s_std_lo: float = 0.0)

Remove inaccurate configurations based on committee error. This is used to revise the dataset.

Returns:

  • extxyz_file ( str ) –

    revise configurations

Note: See parameters in functions committee_error and committee_judge.

select_candidate_SevenNet(extxyz_file: str, checkpoint_files: list, sevenn_args: dict = {}, rel_force: float = None, compute_stress: bool = True, rel_stress: float = None, e_std_hi: float = 0.1, e_std_lo: float = 0.0, f_std_hi: float = 0.1, f_std_lo: float = 0.0, s_std_hi: float = None, s_std_lo: float = 0.0)

Select candidate configurations for DFT calculation using SevenNet models.

Parameters:

  • extxyz_file (str) –

    extended xyz file containing multiples configurations

  • checkpoint_files (list) –

    list of checkpoint_files files SevenNet models

  • sevenn_args (dict, default: {} ) –

    arguments for SevenNetCalculator. Defaults to {}.

Returns:

  • extxyz_file ( str ) –

    candidate configurations

remove_inaccurate_SevenNet(extxyz_file: str, checkpoint_files: list, sevenn_args: dict = {}, rel_force: float = None, compute_stress: bool = True, rel_stress: float = None, e_std_hi: float = 0.1, e_std_lo: float = 0.0, f_std_hi: float = 0.1, f_std_lo: float = 0.0, s_std_hi: float = None, s_std_lo: float = 0.0)

Remove inaccurate configurations based on committee error, using SevenNet models.

Parameters:

  • extxyz_file (str) –

    extended xyz file containing multiples configurations

  • checkpoint_files (list) –

    list of checkpoint_files files SevenNet models

  • sevenn_args (dict, default: {} ) –

    arguments for SevenNetCalculator. Defaults to {}.

Returns:

  • extxyz_file ( str ) –

    revised configurations

simple_lmpdump2extxyz(lmpdump_file: str, extxyz_file: str)

Convert LAMMPS dump file to extended xyz file. This is very simple version, only convert atomic positions, but not stress tensor.

base

Classes:

Attributes:

logger = init_alff_logger() module-attribute

Workflow(param_file: str, machine_file: str, schema_file: str = '')

Base class for workflows.

Workflow is the central part of ALFF. Each workflow contains list of stages to be executed.

Subclass should reimplement
  • __init__(): initialize the workflow, need to override these attributes:
    • self.stage_map
    • self.wf_name
  • run(): the main function to run the workflow. The default implementation is a loop over stages in self.stage_map, just for simple workflow. For complex workflow (e.g. with iteration like active learning), need to reimplement the .run() function.
Example
class WorkflowExample(Workflow):
    def __init__(self, param_file: str, machine_file: str):
        super().__init__(param_file, machine_file, SCHEMA_EXAMPLE)
        self.stage_map = {
            "stage_name1": stage_function1,
            "stage_name2": stage_function2,
            "stage_name3": stage_function3,
        }
        self.wf_name = "Name of the workflow"
        return
Notes
  • mdict in this class is a single dictionary containing multiple remote machines, and will be parsed as mdict_list in RemoteOperation class.

Methods:

  • run

    The main function to run the workflow. This default implementation works for simple workflow,

Attributes:

param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
stage_list = self._load_stage_list() instance-attribute
stage_map = {} instance-attribute
wf_name = 'workflow_name' instance-attribute
run()

The main function to run the workflow. This default implementation works for simple workflow, for more complex workflow (e.g. with iteration like active learning), need to reimplement this .run() function.

_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()

RemoteOperation(work_dir, pdict, multi_mdict, mdict_prefix='')

Base class for operations on remote machines.

Each operation includes atleast 3 methods
  • prepare
  • run
  • postprocess
Subclass must reimplement these methods
  • __init__(): initialize the operation, need to override these attributes:
  • prepare(): prepare all things needed for the run() method.
  • postprocess(): postprocess after the run() method.
Notes
  • Before using this class, must prepare file work_dir/task_dirs.yml
  • All paths are in POSIX format, and relative to run_dir (not work_dir).
  • Do not change the run() method unless you know what you are doing.

Methods:

  • prepare

    Prepare all things needed for the run() method.

  • run

    Function to submit jobs to remote machines.

  • postprocess

    Postprocess after the run() method.

Attributes:

op_name = 'Name of the operation' instance-attribute
has_files: list[str] = [] instance-attribute
no_files: list[str] = [] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

Prepare all things needed for the run() method. Note: Must reimplement this method in subclasses.

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()

Postprocess after the run() method. Note: Must reimplement this method in subclasses.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

cli

Functions:

alff_al()

CLI for active learning

alff_finetune()

CLI for fine-tuning

alff_gen()

CLI for data generation

alff_phonon()

CLI for phonon calculation

alff_pes()

CLI for PES scanning calculation

alff_elastic()

CLI for elastic constants calculation

convert_chgnet_to_xyz()

CLI for converting the MPCHGNet dataset to XYZ format

get_cli_args()

Get the arguments from the command line

elastic

Modules:

elastic

Classes:

Functions:

WorkflowElastic(param_file: str, machine_file: str)

Bases: Workflow

Workflow for Elastic tensor calculation.

Methods:

  • run

    The main function to run the workflow. This default implementation works for simple workflow,

Attributes:

stage_map = {'make_structure': make_structure, 'relax_initial_structure': relax_initial_structure, 'strain_and_relax': strain_and_relax, 'compute_stress': compute_stress_strain, 'compute_elastic': compute_elastic} instance-attribute
wf_name = 'ELASTIC CONSTANTS CALCULATION' instance-attribute
param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
stage_list = self._load_stage_list() instance-attribute
run()

The main function to run the workflow. This default implementation works for simple workflow, for more complex workflow (e.g. with iteration like active learning), need to reimplement this .run() function.

_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()
relax_initial_structure(pdict, mdict)

Relax the structure by DFT/MD

strain_and_relax(pdict, mdict)

Scale and relax the structures while fixing box size. Use when want to compute phonon at different volumes.

compute_stress_strain(pdict, mdict)

Compute stress and strain tensors for each scale-relaxed-structure by DFT/MD.

compute_stress_single_structure(work_dir, pdict, mdict)

The function does the following: - generate supercells with small deformation and compute corresponding strain tensor - run DFT/MD minimize calculation to compute stress tensor for each suppercell. - collect stress and strain tensor for each supercell

compute_elastic_tensor_single_structure(work_dir, pdict: dict, mdict: dict)

Compute elastic tensor for a single structure. - Collect stress and strain tensors from calculations on deformed structures. - Compute elastic constants by fitting stress-strain relations.

compute_elastic(pdict: dict, mdict: dict)

Compute elastic constants from stress-strain tensors.

lib_elastic

Classes:

  • Elasticity

    Main class to compute the elastic stiffness tensor of the crystal.

  • ElasticConstant

    Class to manage elastic constants and compute elastic properties.

Functions:

Elasticity(ref_cryst: Atoms, symprec: float = 1e-05)

Bases: object

Main class to compute the elastic stiffness tensor of the crystal. Steps to compute the elastic tensor: - Initialize the class with the reference structure. - Generate deformed structures with 'elementary deformations' - Compute stress for each deformed structure by DFT/MD. - Input the deformed structures with stress tensors to the method fit_elastic_tensor

Parameters:

  • ref_cryst (Atoms) –

    ASE Atoms object, reference structure (relaxed/optimized structure)

  • symprec (float, default: 1e-05 ) –

    symmetry precision to check the symmetry of the crystal

Methods:

  • generate_deformations

    Generate deformed structures with 'elementary deformations' for elastic tensor calculation.

  • fit_elastic_tensor

    Calculate elastic tensor from the stress-strain relation by fitting this relation to the set of linear equations, strains and stresses.

  • get_pressure

    Return external isotropic (hydrostatic) pressure in ASE units.

  • write_cij

    Write the elastic constants to a text file.

  • fit_BM_EOS

    Calculate Birch-Murnaghan Equation of State for the crystal.

  • get_bulk_modulus

    Calculate bulk modulus using the Birch-Murnaghan equation of state.

  • write_MB_EOS

    Write the Birch-Murnaghan EOS parameters to a text file.

  • write_MB_EOS_pv_data

    Write the volume-pressure data to a text file.

Attributes:

ref_cryst = ref_cryst instance-attribute
symprec = symprec instance-attribute
bravais = get_lattice_type(self.ref_cryst, self.symprec)[0] instance-attribute
strain_list = None instance-attribute
stress_list = None instance-attribute
pressure = None instance-attribute
Cij = None instance-attribute
generate_deformations(delta: float = 0.01, n: int = 5)

Generate deformed structures with 'elementary deformations' for elastic tensor calculation. The deformations are created based on the symmetry of the crystal.

Parameters:

  • delta (float, default: 0.01 ) –

    the maximum magnitude of deformation in Angstrom and degrees.

  • n (int, default: 5 ) –

    number of deformations on each non-equivalent axis (number of deformations in each direction)

Returns:

  • list[Atoms]: list of deformed structures. Number of structures = (n * number_of_axes). These structures are then used in MD/DFT to compute the stress tensor.

fit_elastic_tensor(deform_crysts: list[Atoms]) -> tuple[np.array, np.array]

Calculate elastic tensor from the stress-strain relation by fitting this relation to the set of linear equations, strains and stresses. The number of linear equations is computed depends on the symmetry of the crystal.

It is assumed that the crystal is converged (relaxed/optimized) under intended pressure/stress. The geometry and stress on this crystal is taken as the reference point. No additional optimization will be run. Then, the strain and stress tensor is computed for each of the deformed structures (exactly, the stress difference from the reference point).

This function returns tuple of Cij elastic tensor, and the fitting results returned by numpy.linalg.lstsq: Birch coefficients, residuals, solution rank, singular values.

Parameters:

  • deform_crysts (list[Atoms]) –

    list of Atoms objects with calculated deformed structures

Returns:

  • tuple ( tuple[array, array] ) –

    tuple of Cij elastic tensor and fitting results. - Cij: in vector form of Voigt notation. - Bij: float vector, residuals, solution rank, singular values

get_pressure(stress) -> float

Return external isotropic (hydrostatic) pressure in ASE units. If the pressure is positive the system is under external pressure. This is a convenience function to convert output of get_stress function into external pressure.

Parameters:

  • stress(np.array

    stress tensor in Voight (vector) notation as returned by the .get_stress() method.

Return

float: external hydrostatic pressure in ASE units.

write_cij(filename: str = 'cij.txt')

Write the elastic constants to a text file.

Parameters:

  • filename (str, default: 'cij.txt' ) –

    output file name

fit_BM_EOS(deform_crysts: list[Atoms])

Calculate Birch-Murnaghan Equation of State for the crystal.

\[ P(V) = \frac{B_0}{B'_0}\left[\left({\frac{V}{V_0}}\right)^{-B'_0} - 1\right] \]

It's coefficients are estimated using n single-point structures ganerated from the crystal (cryst) by the scan_volumes function between two relative volumes. The BM EOS is fitted to the computed points by least squares method.

Parameters:

  • cryst (Atoms) –

    Atoms object, reference structure (relaxed/optimized structure)

  • deform_crysts (list[Atoms]) –

    list of Atoms objects with calculated deformed structures

Returns:

  • tuple

    tuple of EOS parameters ([V0, B0, B0p], pv data)'.

get_bulk_modulus(deform_crysts: list[Atoms])

Calculate bulk modulus using the Birch-Murnaghan equation of state. The bulk modulus is the B_0 coefficient of the B-M EOS. The units of the result are defined by ASE. To get the result in any particular units (e.g. GPa) you need to divide it by ase.units.::

get_bulk_modulus(cryst)/ase.units.GPa

Parameters:

  • cryst (Atoms) –

    Atoms object, reference structure (relaxed/optimized structure)

  • deform_crysts (list[Atoms]) –

    list of Atoms objects with calculated deformed structures

Returns:

  • float

    bulk modulus B_0 in ASE units.

write_MB_EOS(filename: str = 'BMeos.txt')

Write the Birch-Murnaghan EOS parameters to a text file.

Parameters:

  • filename (str, default: 'BMeos.txt' ) –

    output file name

write_MB_EOS_pv_data(filename: str = 'BMeos_pv_data.txt')

Write the volume-pressure data to a text file.

Parameters:

  • filename (str, default: 'BMeos_pv_data.txt' ) –

    output file name

ElasticConstant(cij_mat: np.array = None, cij_dict: dict = None, bravais_lattice: str = 'Cubic')

Bases: object

Class to manage elastic constants and compute elastic properties.

Parameters:

  • Cij (array) –

    (6, 6) array of Voigt representation of elastic stiffness.

  • bravais_lattice (str, default: 'Cubic' ) –

    Bravais lattice name of the crystal.

  • **kwargs

    dictionary of elastic constants Cij. Where C11, C12, ... C66 : float,

Methods:

  • Cij

    The elastic stiffness constants in Voigt 6x6 format

  • Sij

    The compliance constants in Voigt 6x6 format

  • bulk

    Returns a bulk modulus estimate.

  • shear

    Returns a shear modulus estimate.

Attributes:

bravais = bravais_lattice instance-attribute
Cij() -> np.ndarray

The elastic stiffness constants in Voigt 6x6 format

Sij() -> np.ndarray

The compliance constants in Voigt 6x6 format

bulk(style: str = 'Hill') -> float

Returns a bulk modulus estimate.

Parameters:

  • style (str, default: 'Hill' ) –

    style of bulk modulus. Default value is 'Hill'. - 'Voigt': Voigt estimate. Uses Cij. - 'Reuss': Reuss estimate. Uses Sij. - 'Hill': Hill estimate (average of Voigt and Reuss).

shear(style: str = 'Hill') -> float

Returns a shear modulus estimate.

Parameters:

  • style (str, default: 'Hill' ) –

    style of bulk modulus. Default value is 'Hill'. - 'Voigt': Voigt estimate. Uses Cij. - 'Reuss': Reuss estimate. Uses Sij. - 'Hill': Hill estimate (average of Voigt and Reuss).

func_MEOS(v, v0, b0, b0p)
func_BMEOS(v, v0, b0, b0p)
get_lattice_type(cryst: Atoms, symprec=1e-05) -> tuple[int, str, str, int]

Identify the lattice type and the Bravais lattice of the crystal. The lattice type numbers are (numbering starts from 1): Triclinic (1), Monoclinic (2), Orthorhombic (3), Tetragonal (4), Trigonal (5), Hexagonal (6), Cubic (7)

Parameters:

  • cryst (Atoms) –

    ASE Atoms object

  • symprec (float, default: 1e-05 ) –

    symmetry precision to check the symmetry of the crystal

Returns:

  • tuple ( tuple[int, str, str, int] ) –

    Bravais name, lattice type number (1-7), space-group name, space-group number

generate_elementary_deformations(cryst: Atoms, delta: float = 0.01, n: int = 5, bravais_lattice: str = 'Cubic') -> list[Atoms]

Generate deformed structures with 'elementary deformations' for elastic tensor calculation. The deformations are created based on the symmetry of the crystal and are limited to the non-equivalent axes of the crystal.

Parameters:

  • cryst (Atoms) –

    Atoms object, reference structure (relaxed/optimized structure)

  • delta (float, default: 0.01 ) –

    the maximum magnitude of deformation in Angstrom and degrees.

  • n (int, default: 5 ) –

    number of deformations on each non-equivalent axis (number of deformations in each direction)

  • symprec (float) –

    symmetry precision to check the symmetry of the crystal

Returns:

  • list[Atoms]

    list[Atoms] list of deformed structures. Number of structures = (n * number_of_axes)

deform_1axis(cryst: Atoms, axis: int = 0, delta: float = 0.01) -> Atoms

Return the deformed structure along one of the cartesian directions. The axis is specified as follows:

- tetragonal deformation: 0,1,2 = x,y,z.
- shear deformation: 3,4,5 = yz, xz, xy.

Parameters:

  • cryst (Atoms) –

    reference structure (structure to be deformed)

  • axis (int, default: 0 ) –

    direction of deformation. 0,1,2 = x,y,z; 3,4,5 = yz, xz, xy.

  • delta (float, default: 0.01 ) –

    magnitude of the deformation. Angstrom and degrees.

Return

ase.Atoms: deformed structure

strain_voigt_to_symmetry_matrix(u: list, bravais_lattice: str = 'Cubic') -> np.array

Return the strain matrix to be used in stress-strain equation, to compute elastic tensor. The number of Cij constants depends on the symmetry of the crystal. This strain matrix is computed based on the symmetry to reduce the necessary number of equations to be used in the fitting procedure (also reduce the necessary calculations). Refer Landau's textbook for the details.

- Triclinic: C11, C22, C33, C12, C13, C23, C44, C55, C66, C16, C26, C36, C46, C56, C14, C15, C25, C45
- Monoclinic: C11, C22, C33, C12, C13, C23, C44, C55, C66, C16, C26, C36, C45
- Orthorhombic: C11, C22, C33, C12, C13, C23, C44, C55, C66
- Tetragonal: C11, C33, C12, C13, C44, C66
- Trigonal: C11, C33, C12, C13, C44, C14
- Hexagonal: C11, C33, C12, C13, C44
- Cubic: C11, C12, C44

Parameters:

  • u (list) –

    vector of strain in Voigt notation [ u_xx, u_yy, u_zz, u_yz, u_xz, u_xy ]

  • bravais_lattice (str, default: 'Cubic' ) –

    Bravais lattice name of the lattice

Returns:

  • array

    np.array: Symmetry defined stress-strain equation matrix

get_cij_list(bravais_lattice: str = 'Cubic') -> list[str]

Return the order of elastic constants for the structure

Parameters:

  • bravais_lattice (str, default: 'Cubic' ) –

    Bravais lattice name of the lattice

Return

list: list of strings C_ij the order of elastic constants

get_cij_6x6matrix(cij_dict: dict[float], bravais_lattice: str = 'Cubic') -> np.array

Return the Cij matrix for the structure based on the symmetry of the crystal.

Parameters:

  • cij_dict (dict) –

    dictionary of elastic constants Cij. Where C11, C12, ... C66 : float, Individual components of Cij for a standardized representation:

    • Triclinic: all Cij where i <= j
    • Monoclinic: C11, C12, C13, C15, C22, C23, C25, C33, C35, C44, C46, C55, C66
    • Orthorhombic: C11, C12, C13, C22, C23, C33, C44, C55, C66
    • Tetragonal: C11, C12, C13, C16, C33, C44, C66 (C16 optional)
    • Trigonal: C11, C12, C13, C14, C33, C44
    • Hexagonal: C11, C12, C13, C33, C44, C66 (2*C66=C11-C12)
    • Cubic: C11, C12, C44
    • Isotropic: C11, C12, C44 (2*C44=C11-C12)
  • bravais_lattice (str, default: 'Cubic' ) –

    Bravais lattice name of the lattice

get_voigt_strain_vector(cryst: Atoms, ref_cryst: Atoms = None) -> np.array

Calculate the strain tensor between the deformed structure and the reference structure. Return strain in vector form of Voigt notation, component order: u_{xx}, u_{yy}, u_{zz}, u_{yz}, u_{xz}, u_{xy}.

Parameters:

  • cryst (Atoms) –

    deformed structure

  • ref_cryst (Atoms, default: None ) –

    reference, undeformed structure

Returns:

  • array

    np.array: vector of strain in Voigt notation.

lib_elate

libelastic_lammps

Functions:

postelast_lammps_optimize(work_dir, pdict)

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones. - Convert LAMMPS output to extxyz_labeled.

postelast_lammps_singlepoint(work_dir, pdict)

This function does: - Clean up unlabelled extxyz files - Collect forces from the output files

utilelastic

gdata

Modules:

convert_mpchgnet_to_xyz

Functions:

Attributes:

info_keys = ['uncorrected_total_energy', 'corrected_total_energy', 'energy_per_atom', 'ef_per_atom', 'e_per_atom_relaxed', 'ef_per_atom_relaxed', 'magmom', 'bandgap', 'mp_id'] module-attribute
chgnet_to_ase_atoms(datum: dict[str, dict[str, Any]]) -> list[Atoms]
run_convert()

gendata

Classes:

  • WorkflowGendata

    Workflow for generate initial data for training ML models.

Functions:

WorkflowGendata(param_file: str, machine_file: str)

Bases: Workflow

Workflow for generate initial data for training ML models.

Methods:

  • run

    The main function to run the workflow. This default implementation works for simple workflow,

Attributes:

stage_map = {'make_structure': make_structure, 'optimize_structure': optimize_structure, 'sampling_space': sampling_space, 'run_dft': run_dft, 'collect_data': collect_data} instance-attribute
wf_name = 'DATA GENERATION' instance-attribute
param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
stage_list = self._load_stage_list() instance-attribute
run()

The main function to run the workflow. This default implementation works for simple workflow, for more complex workflow (e.g. with iteration like active learning), need to reimplement this .run() function.

_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()
make_structure(pdict, mdict)

Build structures based on input parameters

optimize_structure(pdict, mdict)

Optimize the structures

sampling_space(pdict, mdict)

Scale and perturb the structures. - Save 2 lists of paths: original and scaled structure paths

run_dft(pdict, mdict)

Run DFT calculations

collect_data(pdict, mdict)

Collect data from DFT simulations

copy_labeled_structure(src_dir: str, dest_dir: str)

Copy labeled structures - First, try copy labeled structure if it exists. - If there is no labeled structure, copy the unlabeled structure.

strain_x_dim(struct_files: list[str], strain_x_list: list[float])

Scale the x dimension of the structures

strain_y_dim(struct_files: list[str], strain_y_list: list[float])

Scale the y dimension of the structures

strain_z_dim(struct_files: list[str], strain_z_list: list[float])

Scale the z dimension of the structures

perturb_structure(struct_files: list, perturb_num: int, perturb_disp: float)

Perturb the structures

_total_struct_num(pdict: dict)

libgen_gpaw

Classes:

OperGendataGpawOptimize(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: RemoteOperation

This class does GPAW optimization for a list of structures in task_dirs.

Methods:

  • prepare

    This function does:

  • postprocess

    This function does:

  • run

    Function to submit jobs to remote machines.

Attributes:

op_name = 'GPAW optimize' instance-attribute
calc_name = 'gpaw' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare ase_args for GPAW and gpaw_run_file. Note: Must define pdict.dft.calc_args.gpaw{} for this function. - Prepare the task_list - Prepare fordward & backward files - Prepare commandlist_list for multi-remote submission

_prepare_runfile_gpaw()
postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones.

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

OperGendataGpawSinglepoint(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperGendataGpawOptimize

Methods:

Attributes:

op_name = 'GPAW singlepoint' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()
OperGendataGpawAIMD(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperGendataGpawOptimize

Methods:

  • prepare

    Refer to the pregen_gpaw_optimize() function.

  • postprocess

    Refer to the postgen_gpaw_optimize() function.

  • run

    Function to submit jobs to remote machines.

Attributes:

op_name = 'GPAW aimd' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()

Refer to the pregen_gpaw_optimize() function. Note: - structure_dirs: contains the optimized structures without scaling. - strain_structure_dirs: contains the scaled structures.

postprocess()

Refer to the postgen_gpaw_optimize() function.

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()
OperAlGpawSinglepoint(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperGendataGpawOptimize

Methods:

Attributes:

op_name = 'GPAW singlepoint' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()
postprocess()

Do post DFT tasks

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()

util_dataset

Functions:

_divide_idx_list(idx_list: list[int], train_ratio: float, valid_ratio: float) -> tuple[list[int], list[int], list[int]]

Divide list of ints based on given ratios. Resolve any floating point issues.

split_extxyz_dataset(extxyz_files: list[str], train_ratio: float = 0.9, valid_ratio: float = 0.1, seed: int = None, outfile_prefix: str = 'dataset')

Split a dataset into training, validation, and test sets.

If input (train_ratio + valid_ratio) < 1, the remaining data will be used as the test set.

Parameters:

  • extxyz_files (list[str]) –

    List of file paths in EXTXYZ format.

  • train_ratio (float, default: 0.9 ) –

    Ratio of training set. Defaults to 0.9.

  • valid_ratio (float, default: 0.1 ) –

    Ratio of validation set. Defaults to 0.1.

  • seed (Optional[int], default: None ) –

    Random seed. Defaults to None.

  • outfile_prefix (str, default: 'dataset' ) –

    Prefix for output file names. Defaults to "dataset".

read_list_extxyz(extxyz_files: list[str]) -> list[Atoms]

Read a list of EXTXYZ files and return a list of ASE Atoms objects.

merge_extxyz_files(extxyz_files: list[str], outfile: str, sort_by_natoms: bool = True, sort_by_composition: bool = True, sort_pbc_len: bool = True)

Unify multiple EXTXYZ files into a single file.

Parameters:

  • extxyz_files (list[str]) –

    List of EXTXYZ file paths.

  • outfile (str) –

    Output file path.

  • sort_by_natoms (bool, default: True ) –

    Sort by number of atoms. Defaults to True.

  • sort_by_composition (bool, default: True ) –

    Sort by chemical composition. Defaults to True.

  • sort_pbc_len (bool, default: True ) –

    Sort by periodic length. Defaults to True.

Note
  • np.lexsort is used to sort by multiple criteria. np.argsort is used to sort by a single criterion.
  • np.lexsort does not support descending order, so we reverse the sorted indices using idx[::-1].
change_key_in_extxyz(extxyz_file: str, key_pairs: dict[str, str])

Change keys in extxyz file.

Parameters:

  • extxyz_file (str) –

    Path to the extxyz file.

  • key_pairs (dict) –

    Dictionary of key pairs {"old_key": "new_key"} to change. Example: {"old_key": "new_key", "forces": "ref_forces", "stress": "ref_stress"}

Note
  • If Atoms contains internal-keys (e.g., energy, forces, stress, momenta, free_energy,...), there will be a SinglePointCalculator object included to the Atoms, and these keys are stored in dict atoms.calc.results or can be accessed using .get_() methods.
  • These internal-keys are not stored in atoms.arrays or atoms.info. If we want to store (and access) these properties in atoms.arrays or atoms.info, we need to change these internal-keys to custom-keys (e.g., ref_energy, ref_forces, ref_stress, ref_momenta, ref_free_energy,...).
remove_key_in_extxyz(extxyz_file: str, key_list: list[str])

Remove unwanted keys from extxyz file to keep it clean.

_struct_selection_fingerprint(struct: Atoms, tol: float = 1e-06) -> dict

Build a fingerprint dict with relevant info for selection filters.

select_structs_from_extxyz(extxyz_file: str, has_symbols: list = None, only_symbols: list = None, exact_symbols: list = None, has_properties: list = None, only_properties: list = None, has_columns: list = None, only_columns: list = None, natoms: int = None, tol: float = 1e-06) -> list[Atoms]

Choose frames from a extxyz trajectory file, based on some criteria.

Parameters:

  • extxyz_file (str) –

    Path to the extxyz file.

  • has_symbols (list, default: None ) –

    List of symbols that each frame must have at least one of them.

  • only_symbols (list, default: None ) –

    List of symbols that each frame must have only these symbols.

  • exact_symbols (list, default: None ) –

    List of symbols that each frame must have exactly these symbols.

  • has_properties (list, default: None ) –

    List of properties that each frame must have at least one of them.

  • only_properties (list, default: None ) –

    List of properties that each frame must have only these properties.

  • has_columns (list, default: None ) –

    List of columns that each frame must have at least one of them.

  • only_columns (list, default: None ) –

    List of columns that each frame must have only these columns.

  • natoms (int, default: None ) –

    total number of atoms in frame.

  • tol (float, default: 1e-06 ) –

    Tolerance for comparing floating point numbers.

sort_atoms_by_position(struct: Atoms) -> Atoms

Sorts the atoms in an Atoms object based on their Cartesian positions.

are_structs_identical(input_struct1: Atoms, input_struct2: Atoms, tol=1e-06) -> bool

Checks if two Atoms objects are identical by first sorting them and then comparing their attributes.

Parameters:

  • input_struct1 (Atoms) –

    First Atoms object.

  • input_struct2 (Atoms) –

    Second Atoms object.

  • tol (float, default: 1e-06 ) –

    Tolerance for position comparison.

Returns:

  • bool ( bool ) –

    True if the structures are identical, False otherwise.

are_structs_equivalent(struct1: Atoms, struct2: Atoms) -> bool

Check if two Atoms objects are equivalent using ase.utils.structure_comparator.SymmetryEquivalenceCheck.compare()

Parameters:

  • struct1 (Atoms) –

    First Atoms object.

  • struct2 (Atoms) –

    Second Atoms object.

Returns:

  • bool ( bool ) –

    True if the structures are equivalent, False otherwise.

Notes
  • It is not clear what is "equivalent"?
remove_duplicate_structs_serial(extxyz_file: str, tol=1e-06) -> None

Check if there are duplicate structs in a extxyz file.

Parameters:

  • extxyz_file (str) –

    Path to the extxyz file.

  • tol (float, default: 1e-06 ) –

    Tolerance for comparing atomic positions. Defaults to 1e-6.

Returns:

  • None

    extxyz_file without duplicate structs.

_compare_with_uniques(struct, uniques, tol)

Helper: check if struct matches any in uniques.

remove_duplicate_structs_parallel(extxyz_file: str, tol=1e-06, n_jobs=None) -> None

Remove duplicate structures from an extxyz file using built-in parallelism.

Parameters:

  • extxyz_file (str) –

    Path to the extxyz file.

  • tol (float, default: 1e-06 ) –

    Tolerance for comparing atomic positions. Defaults to 1e-6.

  • n_jobs (int, default: None ) –

    Number of worker processes. Defaults to None (use all cores).

Returns:

  • None

    None. Writes a new file with unique structures.

Notes
  • This approach is the O(N²) pairwise checks, so it scales badly as the number of structures grows.
  • This parallel version has not helped much in practice. Use the hashing approach instead.
_struct_unique_fingerprint(struct, tol=1e-06)

Create a hashable fingerprint consistent with are_structs_identical logic. Notes: - The map(tuple, …) trick is a quick way to turn a 2D NumPy array into something hashable (since plain NumPy arrays aren't)

Example
# If call tuple() on 2D NumPy array of shape (3, 3) (the cell matrix): tuple(np.array([[1,2,3],[4,5,6],[7,8,9]]))
# Output gives a tuple of rows as arrays: (array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]))
# But `array([...])` objects aren't hashable → can't go in a `set`.
# `map(tuple, ...)` converts each row into a plain tuple of ints: ((1,2,3), (4,5,6), (7,8,9))
# So the purpose of `map(tuple, …)` = "turn each row (which is an array) into a tuple".
remove_duplicate_structs_hash(extxyz_file: str, tol=1e-06) -> None

Remove duplicate structures using hashing (very fast).

Notes
  • Much less memory overhead compared to pairwise are_structs_identical calls.
  • This reduces duplicate checking to O(N) instead of O(N²). No parallelism needed — it's already O(N)

pes

Modules:

libpes_gpaw

Classes:

OperPESGpawOptimize(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperGendataGpawOptimize

This class does GPAW optimization for a list of structures in task_dirs. This class can also be used for phonon GPAW optimization

Methods:

Attributes:

op_name = 'GPAW optimize' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()

This function does: - Prepare ase_args for GPAW and gpaw_run_file. Note: Must define pdict.dft.calc_args.gpaw{} for this function. - Prepare the task_list - Prepare fordward & backward files - Prepare commandlist_list for multi-remote submission

postprocess()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()
OperPESGpawOptimizeFixatom(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperPESGpawOptimize

Perform optimization with some atoms fixed.

Methods:

Attributes:

op_name = 'GPAW optimize fixed atoms' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()
_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()

libpes_lammps

Classes:

OperPESLammpsOptimize(work_dir, pdict, multi_mdict, mdict_prefix='lammps')

Bases: RemoteOperation

This class does LAMMPS optimization for a list of structures in task_dirs. This class can also be used for phonon LAMMPS optimization alff.phonon.libphonon_lammps.py

Methods:

  • prepare

    This function does:

  • postprocess

    This function does:

  • run

    Function to submit jobs to remote machines.

Attributes:

op_name = 'LAMMPS optimize' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = ['frame_label.lmpdump'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare lammps_optimize and lammps_input files. - Convert extxyz to lmpdata. - Copy potential file to work_dir.

  • Prepare the task_list
  • Prepare fordward & backward files
  • Prepare commandlist_list for multi-remote submission
_prepare_runfile_lammps()
postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones. - Convert LAMMPS output to extxyz_labeled.

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

OperPESLammpsOptimizeFixatom(work_dir, pdict, multi_mdict, mdict_prefix='lammps')

Bases: OperPESLammpsOptimize

The same base class, only need to redefine the .prepare() method.

Methods:

  • prepare

    This function does:

  • run

    Function to submit jobs to remote machines.

  • postprocess

    This function does:

Attributes:

op_name = 'LAMMPS optimize fixed atoms' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = ['frame_label.lmpdump'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare lammps_optimize and lammps_input files. - Convert extxyz to lmpdata. - Copy potential file to work_dir.

  • Prepare the task_list
  • Prepare fordward & backward files
  • Prepare commandlist_list for multi-remote submission
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones. - Convert LAMMPS output to extxyz_labeled.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_lammps()

pes_scan

Implementation of 2d PES scanning. - Idea is to incrementally change the relative positions between 2 groups of atoms while calculating the energy of the system.

Classes:

  • WorkflowPes

    Workflow for PES scanning calculation.

Functions:

  • relax_initial_structure

    Relax the structure by DFT/MD

  • scanning_space

    Displace a group of atoms in a structure to generate a series of structures

  • compute_energy

    Compute energy for each scan-structure by DFT/MD.

  • compute_pes

    Collect energies computed in the previous stage and do some post-processing.

WorkflowPes(param_file: str, machine_file: str)

Bases: Workflow

Workflow for PES scanning calculation.

Methods:

  • run

    The main function to run the workflow. This default implementation works for simple workflow,

Attributes:

stage_map = {'make_structure': make_structure, 'relax_initial_structure': relax_initial_structure, 'scanning_space': scanning_space, 'compute_energy': compute_energy, 'compute_pes': compute_pes} instance-attribute
wf_name = 'PES SCANNING CALCULATION' instance-attribute
param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
stage_list = self._load_stage_list() instance-attribute
run()

The main function to run the workflow. This default implementation works for simple workflow, for more complex workflow (e.g. with iteration like active learning), need to reimplement this .run() function.

_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()
relax_initial_structure(pdict, mdict)

Relax the structure by DFT/MD

scanning_space(pdict, mdict)

Displace a group of atoms in a structure to generate a series of structures - Save 2 lists of paths: original and scaled structure paths

compute_energy(pdict, mdict)

Compute energy for each scan-structure by DFT/MD. Using conditional optimization: fix atoms and optimize the rest.

compute_pes(pdict, mdict)

Collect energies computed in the previous stage and do some post-processing.

utilpes

Functions:

scan_x_dim(struct_files: list, idxs: list, scan_dx_list: list)

Scan in the x dimension

scan_y_dim(struct_files: list, idxs: list, scan_dy_list: list)

Scan in the y dimension

scan_z_dim(struct_files: list, idxs: list, scan_dz_list: list)

Scan in the z dimension

displace_group_atoms_2d(struct: Atoms, idxs: list[int], dx: float = 0.0, dy: float = 0.0, dz: float = 0.0) -> Atoms

Displace a selected group of atoms by (dx, dy, dz).

Parameters:

  • struct (Atoms) –

    ASE Atoms.

  • idxs (list[int]) –

    Indices of atoms to displace.

  • dx, dy, dz

    Displacements (Å).

Returns:

  • Atoms

    A new Atoms with updated positions and cell (positions are NOT affinely scaled).

Notes
  • This function assumes the structure is 2D, and the cell is orthogonal in z direction.
  • After displacement, if any atom move outside the current boundaries, it will be wrapped to the cell.
  • The displacement of atoms may broke the periodicity at cell's boundaries. A minimization step is needed update the cell correctly.
_filter_atoms(struct: Atoms, filters: dict) -> list[int]

Get atom indices from structure based on filters (intersection of all filters).

Parameters:

  • struct (Atoms) –

    ASE Atoms object.

  • filters (dict) –

    Supported keys: - "elements": list[str], e.g., ['Mg', 'O'] - "above_mean_z": bool - "below_mean_z": bool - "min_z": float (keep atoms with z > min_z) - "max_z": float (keep atoms with z < max_z)

Returns:

  • list[int]

    list[int]: Atom indices satisfying all filters.

Raises:

  • ValueError

    If no filters are provided, or no atoms match.

_extract_dxdydz(mystring: str) -> tuple[float, float, float]

Extract dx, dy, dz from a string like xxx_dx0.1_dy-0.2_dz0.3

_extract_interlayer_distance(struct: Atoms, fix_idxs: list[int]) -> float

Extract interlayer distance from fix_atoms list

mapping_dxdydz_to_cartesian(dxdydz: np.ndarray, struct_cell: np.ndarray)

Sampling points are in (u,v) coordinates along cell vectors that may not orthogonal. This function transform sampling points to real Cartesian coordinates

Parameters:

  • dxdydz (ndarray) –

    array (N,3) containing (dx, dy, dz) for N sampling points

  • struct_cell (ndarray) –

    array (3,3) containing cell vectors

interp_pes_xy(df: pl.DataFrame, grid_size: float = 0.05) -> pl.DataFrame

Interpolate PES surface in the xy plane. Args: df: PES raw data file with columns: dx dy energy grid_size: grid size (Å) for interpolation Returns: df: DataFrame with columns: grid_x, grid_y, energy/atom

interp_pes_z(df: pl.DataFrame, grid_size: float = 0.05) -> pl.DataFrame

Interpolate PES curve in the z direction. Args: df: PES raw data with columns: dz energy grid_size: grid size (Å) for interpolation Returns: df: DataFrame with columns: grid_z, energy/atom

plot_pes_xy(file_pes_grid: str, file_pes_raw: str | None = None)

Plot PES surface in the xy plane. Args: file_pes_grid: file containing PES data interpolated on a grid file_pes_raw: file containing raw PES data (optional, to plot input data points)

plot_pes_z(file_pes_grid: str, file_pes_raw: str | None = None)

Plot PES surface in the xy plane. Args: file_pes_grid: file containing PES data interpolated on a grid file_pes_raw: file containing raw PES data (optional, to plot input data points)

plot_pes_3d()

phonon

Modules:

libpho_gpaw

Classes:

OperPhononGpawOptimize(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperPESGpawOptimize

Methods:

Attributes:

op_name = 'GPAW optimize' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()
_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()
OperPhononGpawOptimizeFixbox(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperPESGpawOptimize

Only need to redefine the prepare() method, to fix box during optimization.

Methods:

Attributes:

op_name = 'GPAW optimize fixed box' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()
_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()
OperPhononGpawSinglepoint(work_dir, pdict, multi_mdict, mdict_prefix='gpaw')

Bases: OperPESGpawOptimize

Need to redefine the prepare() and postprocess() methods

Methods:

Attributes:

op_name = 'GPAW Singlepoint' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = [FILE_FRAME_LABEL] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
calc_name = 'gpaw' instance-attribute
prepare()
postprocess()

This function does: - Clean up unlabelled extxyz files - Collect forces from the output files

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_gpaw()

libpho_lammps

Classes:

OperPhononLammpsOptimize(work_dir, pdict, multi_mdict, mdict_prefix='lammps')

Bases: OperPESLammpsOptimize

Methods:

  • prepare

    This function does:

  • run

    Function to submit jobs to remote machines.

  • postprocess

    This function does:

Attributes:

op_name = 'LAMMPS optimize' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = ['frame_label.lmpdump'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare lammps_optimize and lammps_input files. - Convert extxyz to lmpdata. - Copy potential file to work_dir.

  • Prepare the task_list
  • Prepare fordward & backward files
  • Prepare commandlist_list for multi-remote submission
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones. - Convert LAMMPS output to extxyz_labeled.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_lammps()
OperPhononLammpsOptimizeFixbox(work_dir, pdict, multi_mdict, mdict_prefix='lammps')

Bases: OperPESLammpsOptimize

Only need to redefine the prepare() method, to fix box during optimization.

Methods:

  • prepare

    This function does:

  • run

    Function to submit jobs to remote machines.

  • postprocess

    This function does:

Attributes:

op_name = 'LAMMPS optimize fixed box' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = ['frame_label.lmpdump'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare lammps_optimize and lammps_input files. - Convert extxyz to lmpdata. - Copy potential file to work_dir.

  • Prepare the task_list
  • Prepare fordward & backward files
  • Prepare commandlist_list for multi-remote submission
run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones. - Convert LAMMPS output to extxyz_labeled.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_lammps()
OperPhononLammpsSinglepoint(work_dir, pdict, multi_mdict, mdict_prefix='lammps')

Bases: OperPESLammpsOptimize

Class to run LAMMPS singlepoint calculation, used for phonon calculation. Notes: the .postprocess() method returns set_of_forces, a 3D array.

Methods:

  • prepare

    This function does:

  • postprocess

    This function does:

  • run

    Function to submit jobs to remote machines.

Attributes:

op_name = 'LAMMPS optimize' instance-attribute
has_files = [FILE_FRAME_unLABEL] instance-attribute
no_files = ['frame_label.lmpdump'] instance-attribute
commandlist_list: list[list[str]] = [] instance-attribute
forward_files: list[str] = [] instance-attribute
backward_files: list[str] = [] instance-attribute
forward_common_files: list[str] = [] instance-attribute
backward_common_files: list[str] = [] instance-attribute
work_dir = work_dir instance-attribute
mdict_prefix: str = mdict_prefix instance-attribute
pdict = pdict instance-attribute
mdict_list = self._load_multi_mdict(multi_mdict) instance-attribute
task_dirs = self._load_task_dirs() instance-attribute
prepare()

This function does: - Prepare lammps_optimize and lammps_input files. - Convert extxyz to lmpdata. - Copy potential file to work_dir.

  • Prepare the task_list
  • Prepare fordward & backward files
  • Prepare commandlist_list for multi-remote submission
postprocess()

This function does: - Remove unlabeled .extxyz files, just keep the labeled ones. - Convert LAMMPS output to extxyz_labeled.

run()

Function to submit jobs to remote machines. Note: - Orginal taks_dirs is relative to run_dir, and should not be changed. But the sumbmission function needs taks_dirs relative path to work_dir, so we make temporary change here.

_load_task_dirs() -> list[str]

Load task directories from work_dir/task_dirs.yml.

_load_multi_mdict(multi_mdict) -> list[dict]

Load multiple mdicts from the mdict_list.

_filter_task_dirs()

Function to filter already run structures.

_prepare_runfile_lammps()

phonon

Classes:

Functions:

  • make_structure_phonon

    Make initial structure for phonon calculation. Recommended settings:

  • relax_initial_structure

    Relax the structure by DFT/MD

  • strain_and_relax

    Scale and relax the structures while fixing box size. Use when want to compute phonon at different volumes.

  • compute_force

    Compute forces for each scale-relaxed-structure by DFT/MD.

  • compute_force_one_scaledstruct

    Run DFT/MD single-point calculations to compute forces for each relaxed structure (the previous step generate a list of scaled&relaxed structures. This function works on each of them).

  • compute_phonon

    Compute phonon properties by phonopy functions.

WorkflowPhonon(param_file: str, machine_file: str)

Bases: Workflow

Workflow for phonon calculation.

Methods:

  • run

    The main function to run the workflow. This default implementation works for simple workflow,

Attributes:

stage_map = {'make_structure': make_structure_phonon, 'relax_initial_structure': relax_initial_structure, 'strain_and_relax': strain_and_relax, 'compute_force': compute_force, 'compute_phonon': compute_phonon} instance-attribute
wf_name = 'PHONON CALCULATION' instance-attribute
param_file = param_file instance-attribute
machine_file = machine_file instance-attribute
schema_file = schema_file instance-attribute
pdict = loadconfig(self.param_file) instance-attribute
mdict = loadconfig(self.machine_file) instance-attribute
stage_list = self._load_stage_list() instance-attribute
run()

The main function to run the workflow. This default implementation works for simple workflow, for more complex workflow (e.g. with iteration like active learning), need to reimplement this .run() function.

_load_stage_list()
_validate_config()
_update_config()
_print_intro()
_print_outro()
make_structure_phonon(pdict, mdict)

Make initial structure for phonon calculation. Recommended settings: 1. Use supercell size to build the input structure. 2. supercell_matrix = [n1, n2, n3] # no matter what the input structure is. 3. Then, use auto_primitive_cell to find the primitive cell from the input structure. This works, but sometime gives unstable result. Use with caution.

relax_initial_structure(pdict, mdict)

Relax the structure by DFT/MD

strain_and_relax(pdict, mdict)

Scale and relax the structures while fixing box size. Use when want to compute phonon at different volumes.

compute_force(pdict, mdict)

Compute forces for each scale-relaxed-structure by DFT/MD.

compute_force_one_scaledstruct(work_dir: str, pdict, mdict)

Run DFT/MD single-point calculations to compute forces for each relaxed structure (the previous step generate a list of scaled&relaxed structures. This function works on each of them). The function does the following: - Initialize the phonopy object - generate supercell_list with displacements - run DFT/MD single-point calculation to compute forces for each supercell - assign forces back to phonopy object - save the phonopy object to a file for latter post-processing

compute_phonon(pdict, mdict)

Compute phonon properties by phonopy functions.

utilpho

Notes
  • Phonon calculations rely on a structure that is tightly converged. It is recommended to run a pre-relaxation with opt_params: {"fmax": 1e-3} or tighter before running phonon calculations.
  • [Notice about displacement distance: "A too small displacement distance can lead to numerical noise, while a too large displacement distance can lead to anharmonic effects. A typical value is 0.01-0.05 Angstrom.", But, some notes say 0.05-0.08 Angstroms are need to converge!
Info

Functions:

convert_phonopy2ase(struct_ph: PhonopyAtoms) -> Atoms
convert_ase2phonopy(struct: Atoms) -> PhonopyAtoms
get_primitive_spglib(struct: Atoms, no_idealize: bool = True, symprec=1e-05, angle_tolerance=-1.0) -> Atoms

Find the primitive cell using spglib.standardize_cell

Parameters:

  • struct (Atoms) –

    ASE's structure object.

  • no_idealize (bool, default: True ) –

    Whether to avoid idealizing the cell shape (lengths and angles). Default is True.

  • symprec (float, default: 1e-05 ) –

    Symmetry tolerance. Default is 1e-5.

  • angle_tolerance (float, default: -1.0 ) –

    Angle tolerance. Default is -1.0 (use sp

Note
  • IMPORTANT: Using this function in phonon calculations is unstable. Use with caution.
    • Since spglib.find_primitive may fail to find the primitive cell for some structures.
    • Or the returned primitive cell may not has right symmetry. This can lead to issues in phonon calculations (e.g., negative frequencies).
  • Must use .get_scaled_positions() to define the cell in spglib.
get_primitive_phonopy(struct: Atoms, symprec=1e-05) -> Atoms

Find the primitive cell using phonopy's get_primitive() function. This is more robust than spglib.

Parameters:

  • struct (Atoms) –

    ASE's structure object.

  • symprec (float, default: 1e-05 ) –

    Symmetry tolerance. Default is 1e-5.

get_band_path(atoms: Atoms, path_str: str = None, npoints: int = 61, path_frac=None, labels=None)
get_band_structure(work_dir, pdict)
get_DOS_n_PDOS(work_dir, pdict)
get_thermal_properties(work_dir, pdict)

util

Modules:

ase_tool

Functions:

build_struct(argdict: dict) -> Atoms

Build atomic configuration, using library ase.build

Supported structure types: - bulk: sc, fcc, bcc, tetragonal, bct, hcp, rhombohedral, orthorhombic, mcl, diamond, zincblende, rocksalt, cesiumchloride, fluorite or wurtzite. - molecule: molecule - mx2: MX2 - graphene: graphene

Parameters:

  • argdict (dict) –

    Parameters dictionary

Returns:

  • struct ( Atoms ) –

    ASE Atoms object

Notes
  • build.graphene() does not set the cell c vector along z axis, so we need to modify it manually.
sort_task_dirs(task_dirs: list[str], work_dir: str) -> list[str]

Sort the structure paths by its supercell size. This helps to chunk the tasks with similar supercell size together (similar supercell size means similar k-point number), which then lead to running DFT calculations in similar time, avoiding the situation that some tasks are finished while others are still running.

key

Attributes:

time_str = time.strftime('%y%m%d_%H%M%S') module-attribute
DIR_LOG = 'log' module-attribute
FILE_LOG_ALFF = f'{DIR_LOG}/{time_str}_alff.log' module-attribute
FILE_ITERLOG = '_alff.iter' module-attribute
DIR_TRAIN = '00_train' module-attribute
DIR_MD = '01_md' module-attribute
DIR_DFT = '02_dft' module-attribute
DIR_DATA = '03_data' module-attribute
DIR_TMP = 'tmp_dir' module-attribute
DIR_TMP_DATA = 'copy_data' module-attribute
DIR_TMP_MODEL = 'copy_model' module-attribute
FILE_DATAPATH = 'data_paths.yml' module-attribute
FILE_MODELPATH = 'model_paths.yml' module-attribute
FILE_CHECKPOINT_PATH = 'checkpoint_paths.yml' module-attribute
FILE_ARG_TRAIN = 'arg_train.yml' module-attribute
FILE_TRAJ_MD = 'traj_md.extxyz' module-attribute
FILE_TRAJ_MD_CANDIDATE = FILE_TRAJ_MD.replace('.extxyz', '_candidate.extxyz') module-attribute
FILE_ITER_DATA = 'data_label.extxyz' module-attribute
FILE_COLLECT_DATA = 'collect_data_label.extxyz' module-attribute
FMT_ITER = '04d' module-attribute
FMT_STAGE = '02d' module-attribute
FMT_MODEL = '02d' module-attribute
FMT_STRUCT = '05d' module-attribute
FMT_TASK_MD = '06d' module-attribute
FMT_TASK_DFT = '06d' module-attribute
RUNFILE_LAMMPS = 'cli_lammps.lmp' module-attribute
FILE_ARG_LAMMPS = 'arg_lammps.yml' module-attribute
FILE_ARG_ASE = 'arg_ase.yml' module-attribute
SCRIPT_ASE_PATH = f'{ALFF_ROOT}/util/script_ase' module-attribute
SCHEMA_ASE_RUN = f'{ALFF_ROOT}/util/script_ase/schema_ase_run.yml' module-attribute
SCHEMA_LAMMPS = f'{ALFF_ROOT}/util/script_lammps/schema_lammps.yml' module-attribute
SCHEMA_ACTIVE_LEARN = f'{ALFF_ROOT}/al/schema_active_learn.yml' module-attribute
SCHEMA_FINETUNE = f'{ALFF_ROOT}/al/schema_finetune.yml' module-attribute
DIR_MAKE_STRUCT = '00_make_structure' module-attribute
DIR_STRAIN = '01_strain' module-attribute
DIR_GENDATA = '02_gendata' module-attribute
FILE_FRAME_unLABEL = 'conf.extxyz' module-attribute
FILE_FRAME_LABEL = 'conf_label.extxyz' module-attribute
FILE_TRAJ_LABEL = 'traj_label.extxyz' module-attribute
SCHEMA_ASE_BUILD = f'{ALFF_ROOT}/util/script_ase/schema_ase_build.yml' module-attribute
SCHEMA_GENDATA = f'{ALFF_ROOT}/gdata/schema_gendata.yml' module-attribute
SCHEMA_PHONON = f'{ALFF_ROOT}/phonon/schema_phonon.yml' module-attribute
SCHEMA_ELASTIC = f'{ALFF_ROOT}/elastic/schema_elastic.yml' module-attribute
SCHEMA_PES_SCAN = f'{ALFF_ROOT}/pes/schema_pes_scan.yml' module-attribute
DIR_SUPERCELL = '01_supercell' module-attribute
DIR_PHONON = '02_phonon' module-attribute
FILE_PHONOPYwFORCES = 'phonopy_with_forces.yml' module-attribute
DIR_ELASTIC = '02_elastic' module-attribute
DIR_SCAN = '01_scan' module-attribute
DIR_PES = '02_pes' module-attribute

script_ase

Modules:

cli_ase_md

Some notes: - Run MD in ase following this tutorial: https://wiki.fysik.dtu.dk/ase/tutorials/md/md.html - For MD run, control symmetry to avoid error: broken symmetry. - Must set txt='calc.txt' in GPAW calculator for backward files. - Defines some print functions that can attach to ASE's dynamics object - param_yaml must contain - a dict ase_calc define calculator. - a dict md with ASE MD parameters.

Functions:

Attributes:

pdict = get_cli_args() module-attribute
ase_calc = pdict.get('calc_args', {}).get('ase', {}) module-attribute
code_lines = f.read() module-attribute
struct_args = pdict['structure'] module-attribute
extxyz_file = struct_args['from_extxyz'] module-attribute
atoms = read(extxyz_file, format='extxyz', index='-1') module-attribute
input_pbc = struct_args.get('pbc', False) module-attribute
md_args = {'ensemble': 'NVE', 'dt': 1, 'temp': 300, 'thermostat': 'langevin', 'barostat': 'parrinello_rahman'} module-attribute
input_md_args = pdict.get('md', {}) module-attribute
thermostat = md_args['thermostat'] module-attribute
support_thermostats = ['langevin', 'nose_hoover', 'nose_hoover_chain'] module-attribute
barostat = md_args['barostat'] module-attribute
support_barostats = ['parrinello_rahman', 'iso_nose_hoover_chain', 'aniso_nose_hoover_chain'] module-attribute
dt = md_args['dt'] * units.fs module-attribute
temp = md_args['temp'] module-attribute
ensemble = md_args['ensemble'] module-attribute
dyn = VelocityVerlet(atoms, timestep=dt) module-attribute
friction = md_args.get('langevin_friction', 0.002) / units.fs module-attribute
tdamp = md_args.get('tdamp', 100) module-attribute
stress = md_args.get('press', None) module-attribute
stress_in_eVA3 = stress / units.GPa module-attribute
pfactor = md_args.get('pfactor', 2000000.0) module-attribute
mask = md_args.get('mask', None) module-attribute
pdamp = barostat.get('pdamp', 1000) module-attribute
equil_steps = md_args.get('equil_steps', 0) module-attribute
num_frames = md_args.get('num_frames', 1) module-attribute
traj_freq = md_args.get('traj_freq', 1) module-attribute
nsteps = num_frames * traj_freq module-attribute
get_cli_args()

Get the arguments from the command line

print_dynamic(atoms=atoms, filename='calc_dyn_properties.txt')

Function to print the potential, kinetic and total energy. Note: Stress printed in this file in GPa, but save in EXTXYZ in eV/Angstrom^3.

write_dyn_extxyz(atoms=atoms, filename='traj_md.extxyz')
cli_gpaw_aimd

Some notes: - Run MD in ase following this tutorial: https://wiki.fysik.dtu.dk/ase/tutorials/md/md.html - For MD run, control symmetry to avoid error: broken symmetry. - Must set txt='calc.txt' in GPAW calculator for backward files. - param_yaml must contain - a dict gpaw_calc with GPAW parameters. - a dict md with ASE MD parameters.

Functions:

Attributes:

pdict = get_cli_args() module-attribute
calc_args = pdict.get('calc_args', {}) module-attribute
gpaw_args = calc_args.get('gpaw', {}) module-attribute
gpaw_params = {'mode': {'name': 'pw', 'ecut': 500}, 'xc': 'PBE', 'convergence': {'energy': 1e-06, 'density': 0.0001, 'eigenstates': 1e-08}, 'occupations': {'name': 'fermi-dirac', 'width': 0.01}, 'txt': 'calc_aimd.txt', 'symmetry': 'off'} module-attribute
calc_pw = GPAW(**gpaw_params) module-attribute
dftd3_args = calc_args.get('dftd3', {}) module-attribute
xc = gpaw_params['xc'].lower() module-attribute
calc_d3 = DFTD3(method=xc, **dftd3_args) module-attribute
calc = SumCalculator([calc_pw, calc_d3]) module-attribute
struct_args = pdict['structure'] module-attribute
extxyz_file = struct_args['from_extxyz'] module-attribute
atoms = read(extxyz_file, format='extxyz', index='-1') module-attribute
input_pbc = struct_args.get('pbc', False) module-attribute
md_args = {'ensemble': 'NVE', 'dt': 1, 'temp': 300, 'thermostat': 'langevin', 'barostat': 'parrinello_rahman'} module-attribute
input_md_args = pdict.get('md', {}) module-attribute
thermostat = md_args['thermostat'] module-attribute
support_thermostats = ['langevin', 'nose_hoover', 'nose_hoover_chain'] module-attribute
barostat = md_args['barostat'] module-attribute
support_barostats = ['parrinello_rahman', 'iso_nose_hoover_chain', 'aniso_nose_hoover_chain'] module-attribute
dt = md_args['dt'] * units.fs module-attribute
temp = md_args['temp'] module-attribute
ensemble = md_args['ensemble'] module-attribute
dyn = VelocityVerlet(atoms, timestep=dt) module-attribute
friction = md_args.get('langevin_friction', 0.002) / units.fs module-attribute
tdamp = md_args.get('tdamp', 100) module-attribute
stress = md_args.get('press', None) module-attribute
stress_in_eVA3 = stress / units.GPa module-attribute
pfactor = md_args.get('pfactor', 2000000.0) module-attribute
mask = md_args.get('mask', None) module-attribute
pdamp = barostat.get('pdamp', 1000) module-attribute
equil_steps = md_args.get('equil_steps', 0) module-attribute
num_frames = md_args.get('num_frames', 1) module-attribute
traj_freq = md_args.get('traj_freq', 1) module-attribute
nsteps = num_frames * traj_freq module-attribute
struct = atoms.copy() module-attribute
get_cli_args()

Get the arguments from the command line

print_dynamic(atoms=atoms, filename='calc_dyn_properties.txt')

Function to print the potential, kinetic and total energy. Note: Stress printed in this file in GPa, but save in EXTXYZ in eV/Angstrom^3.

write_dyn_extxyz(atoms=atoms, filename='traj_label.extxyz')
cli_gpaw_optimize

Some notes - Must set txt='calc.txt' in GPAW calculator for backward files. - param_yaml must contain - a dict gpaw_calc with GPAW parameters. - a dict optimize with ASE optimization parameters.

Functions:

Attributes:

pdict = get_cli_args() module-attribute
calc_args = pdict.get('calc_args', {}) module-attribute
gpaw_args = calc_args.get('gpaw', {}) module-attribute
gpaw_params = {'mode': {'name': 'pw', 'ecut': 500}, 'xc': 'PBE', 'convergence': {'energy': 1e-06, 'density': 0.0001, 'eigenstates': 1e-08}, 'occupations': {'name': 'fermi-dirac', 'width': 0.01}, 'txt': 'calc_optimize.txt'} module-attribute
calc_pw = GPAW(**gpaw_params) module-attribute
dftd3_args = calc_args.get('dftd3', {}) module-attribute
xc = gpaw_params['xc'].lower() module-attribute
calc_d3 = DFTD3(method=xc, **dftd3_args) module-attribute
calc = SumCalculator([calc_pw, calc_d3]) module-attribute
struct_args = pdict['structure'] module-attribute
extxyz_file = struct_args['from_extxyz'] module-attribute
atoms = read(extxyz_file, format='extxyz', index='-1') module-attribute
input_pbc = struct_args.get('pbc', False) module-attribute
constraint_arg = pdict.get('constraint', None) module-attribute
c = [] module-attribute
fix_idxs = constraint_arg['fix_atoms']['fix_idxs'] module-attribute
symprec = constraint_arg['fix_symmetry'].get('symprec', 1e-05) module-attribute
opt_args = pdict.get('optimize', {}) module-attribute
mask = opt_args.get('mask', None) module-attribute
fmax = opt_args.get('fmax', 0.05) module-attribute
max_steps = opt_args.get('max_steps', 10000) module-attribute
atoms_filter = FrechetCellFilter(atoms, mask=mask) module-attribute
opt = BFGS(atoms_filter) module-attribute
pot_energy = atoms.get_potential_energy() module-attribute
forces = atoms.get_forces() module-attribute
stress = atoms.get_stress() module-attribute
struct = atoms.copy() module-attribute
output_file = extxyz_file.replace('.extxyz', '_label.extxyz') module-attribute
get_cli_args()

Get the arguments from the command line

cli_gpaw_singlepoint

Some notes - Must set txt='calc.txt' in GPAW calculator for backward files. - param_yaml must contain - a dict gpaw_calc with GPAW parameters.

Functions:

Attributes:

pdict = get_cli_args() module-attribute
calc_args = pdict.get('calc_args', {}) module-attribute
gpaw_args = calc_args.get('gpaw', {}) module-attribute
gpaw_params = {'mode': {'name': 'pw', 'ecut': 500}, 'xc': 'PBE', 'convergence': {'energy': 1e-06, 'density': 0.0001, 'eigenstates': 1e-08}, 'occupations': {'name': 'fermi-dirac', 'width': 0.01}, 'txt': 'calc_singlepoint.txt'} module-attribute
calc_pw = GPAW(**gpaw_params) module-attribute
dftd3_args = calc_args.get('dftd3', {}) module-attribute
xc = gpaw_params['xc'].lower() module-attribute
calc_d3 = DFTD3(method=xc, **dftd3_args) module-attribute
calc = SumCalculator([calc_pw, calc_d3]) module-attribute
struct_args = pdict['structure'] module-attribute
extxyz_file = struct_args['from_extxyz'] module-attribute
atoms = read(extxyz_file, format='extxyz', index='-1') module-attribute
input_pbc = struct_args.get('pbc', False) module-attribute
pot_energy = atoms.get_potential_energy() module-attribute
forces = atoms.get_forces() module-attribute
stress = atoms.get_stress() module-attribute
output_file = extxyz_file.replace('.extxyz', '_label.extxyz') module-attribute
get_cli_args()

Get the arguments from the command line

script_lammps

Modules:

lammps_code_creator

Functions:

generate_script_lammps_singlepoint(units: str = 'metal', atom_style: str = 'atomic', dimension: int = 3, pbc: list = [1, 1, 1], read_data: str = 'path_to_file.lmpdata', read_restart: str = None, pair_style: list[str] = None, pair_coeff: list[str] = None, output_script: str = 'cli_script_lammps.lmp', **kwargs)

Generate lammps script for single-point calculation.

Parameters:

  • units (str, default: 'metal' ) –

    Units for lammps. Default "metal"

  • atom_style (str, default: 'atomic' ) –

    Atom style of system. Default "atomic"

  • dimension (int, default: 3 ) –

    Dimension of system. Default 3

  • pbc (list, default: [1, 1, 1] ) –

    Periodic boundary conditions. Default [1, 1, 1]

  • read_data (str, default: 'path_to_file.lmpdata' ) –

    Path to the data file. e.g. "path_to_lmpdata"

  • read_restart (str, default: None ) –

    Path to the restart file. e.g. "path_to_restart". If provided, read_restart is used instead of read_data.

  • output_script (str, default: 'cli_script_lammps.lmp' ) –

    Path to the output script. Default "cli_script_lammps.in"

generate_script_lammps_minimize(units: str = 'metal', atom_style: str = 'atomic', dimension: int = 3, pbc: list = [1, 1, 1], read_data: str = 'path_to_file.lmpdata', read_restart: str = None, pair_style: list[str] = None, pair_coeff: list[str] = None, min_style: str = 'cg', etol: float = 1e-09, ftol: float = 1e-09, maxiter: int = 100000, maxeval: int = 100000, dmax: float = 0.01, press: Union[list[int], float, bool] = [None, None, None], mask: list[int] = [1, 1, 1], couple: str = 'none', output_script: str = 'cli_script_lammps.lmp', **kwargs)

Generate lammps script for minimization.

Parameters:

  • etol (float, default: 1e-09 ) –

    Energy tolerance for minimization. Default 1.0e-9

  • ftol (float, default: 1e-09 ) –

    Force tolerance for minimization. Default 1.0e-9

  • maxiter (int, default: 100000 ) –

    Maximum number of iterations. Default 100000

  • maxeval (int, default: 100000 ) –

    Maximum number of evaluations. Default 100000

  • dmax (float, default: 0.01 ) –

    maximum distance for line search to move (distance units). Default: 0.01

  • press (Union[list[int], float, bool], default: [None, None, None] ) –

    float/1x3 list of Pressure values in GPa. If a single value is provided, it is applied to all directions.

  • mask (list[int], default: [1, 1, 1] ) –

    3x1 list of Mask for pressure. Default [1, 1, 1]. Mask to more control which directions is allowed to relax.

  • couple (str, default: 'none' ) –

    "none", xyz, xy, yz, xz. Default "none"

  • output_script (str, default: 'cli_script_lammps.lmp' ) –

    Path to the output script. Default "cli_script_lammps.in"

For control pressure
  • Only control pressure in the periodic directions.
  • If single value is given, it is assumed to be the pressure in all directions.
  • If three values are given, they are assumed to be the pressure in x, y, and z directions, respectively.
  • **kwargs, to accept unused arguments, any other arguments which may be ignored.
generate_script_lammps_md(units: str = 'metal', atom_style: str = 'atomic', dimension: int = 3, pbc: list = [1, 1, 1], read_data: str = 'path_to_file.lmpdata', read_restart: str = None, pair_style: list[str] = None, pair_coeff: list[str] = None, ensemble: Literal['NVE', 'NVT', 'NPT'] = 'NVE', dt: float = 0.001, num_frames: int = 0, traj_freq: int = 1, equil_steps: int = 0, plumed_file: str = None, thermo_freq: int = 5000, first_minimize: bool = False, temp: float = 300, tdamp: int = 100, thermostat: Literal['nose_hoover_chain', 'langevin'] = 'nose_hoover_chain', press: Optional[Union[float, list[float]]] = None, mask: list[int] = [1, 1, 1], couple: str = 'none', pdamp: int = 1000, barostat: Literal['nose_hoover_chain'] = 'nose_hoover_chain', deform_limit: Optional[float] = None, output_script: str = 'cli_script_lammps.lmp', **kwargs)

Generate lammps script for MD simulation.

Parameters:

  • first_minimize (bool, default: False ) –

    Whether to perform a first minimization before MD simulation. Default False

  • ensemble (Literal['NVE', 'NVT', 'NPT'], default: 'NVE' ) –

    Ensemble for MD simulation. Default "NVE"

  • dt (float, default: 0.001 ) –

    Time step for MD simulation. Default 0.001 ps = 1 fs if unit metal, 1 fs if unit real

  • traj_freq (int, default: 1 ) –

    Frequency to dump trajectory. Default 1

  • num_frames (int, default: 0 ) –

    number of frames to be collected. Then total MD nsteps = (num_frames * traj_freq)

  • equil_steps (int, default: 0 ) –

    Number of steps for first equilibration. Default 0

  • plumed_file (str, default: None ) –

    Path to the plumed file. Default None

  • thermo_freq (int, default: 5000 ) –

    Frequency to print thermo. Default 5000

  • temp (float, default: 300 ) –

    Temperature for MD simulation. Default 300

  • tdamp (int, default: 100 ) –

    Damping time for thermostat. Default 100

  • thermostat (Literal['nose_hoover_chain', 'langevin'], default: 'nose_hoover_chain' ) –

    Thermostat for MD simulation. Default "nose_hoover_chain"

  • press (Union[list[int], float, bool], default: None ) –

    float/1x3 list of Pressure values. If a single value is provided, it is applied to all directions.

  • mask (list[int], default: [1, 1, 1] ) –

    3x1 list of Mask for pressure. Default [1, 1, 1]. Mask to more control which directions is allowed to relax.

  • couple (str, default: 'none' ) –

    "none", xyz, xy, yz, xz. Default "none"

  • pdamp (int, default: 1000 ) –

    Damping time for barostat. Default 1000

  • barostat (Literal['nose_hoover_chain'], default: 'nose_hoover_chain' ) –

    Barostat for MD simulation. Default "nose_hoover_chain"

  • deform_limit (Optional[float], default: None ) –

    Maximum fractional change allowed for any box dimension. The simulation stops if \(abs(L - L0) / L0 > deform_limit\) in any of x, y, or z dim.

  • output_script (str, default: 'cli_script_lammps.lmp' ) –

    Path to the output script. Default "cli_script_lammps.in"

For control pressure
  • Only control pressure in the periodic directions.
  • If single value is given, it is assumed to be the pressure in all directions.
  • If three values are given, they are assumed to be the pressure in x, y, and z directions, respectively.
lmp_section_atom_forcefield(units: str = 'metal', atom_style: str = 'atomic', dimension: int = 3, pbc: list = [1, 1, 1], read_data: str = 'path_to_file.lmpdata', read_restart: str = None, pair_style: list[str] = None, pair_coeff: list[str] = None, **kwargs) -> list[str]

Generate lammps input block for atom and forcefield.

Parameters:

  • read_data (str, default: 'path_to_file.lmpdata' ) –

    Path to the data file. e.g. "path_to_lmpdata"

  • read_restart (str, default: None ) –

    Path to the restart file. e.g. "path_to_restart". If provided, read_restart is used instead of read_data.

  • pair_style (list[str], default: None ) –

    List of pair_style, e.g., ["eam/alloy"]. Default is None

  • pair_coeff (list[str], default: None ) –

    List of pair_coeff,e.g., ["* * Cu.eam.alloy Cu"]. Default is None

lmp_section_common_setting(extra_settings: list | None = None, **kwargs) -> list[str]

Generate lammps input block for common settings. Args: extra_settings (list[str] | None): List of extra settings to be added. Default None.

Notes
  • The fix balance requires setting pair_coeff before it.
lmp_section_minimize(min_style: str = 'cg', etol: float = 1e-09, ftol: float = 1e-09, maxiter: int = 100000, maxeval: int = 100000, dmax: float = 0.01, press: list = [None, None, None], couple: str = 'none', uid: str = None, **kwargs) -> list[str]

Generate lammps input block for minimization.

lmp_section_dynamic_setting(dt: float, temp: float, thermo_freq: int = 5000, **kwargs) -> list[str]
lmp_section_nve(num_frames: int = 0, traj_freq: int = 1, plumed_file: str = None, dump_result: bool = False, uid: str = None, **kwargs) -> tuple[list[str]]
lmp_section_nvt(num_frames: int = 0, traj_freq: int = 1, temp: float = 300, tdamp: int = 100, thermostat: str = 'nose_hoover_chain', plumed_file: str = None, dump_result: bool = False, uid: str = None, **kwargs) -> list[str]
lmp_section_npt(num_frames: int = 0, traj_freq: int = 1, temp: float = 300, tdamp: int = 100, thermostat: str = 'nose_hoover_chain', press: list = [0, 0, 0], pdamp: int = 1000, barostat: str = 'nose_hoover_chain', mask: list[int] = [1, 1, 1], couple: str = 'none', plumed_file: str = None, dump_result: bool = False, deform_limit: float = None, uid: str = None, **kwargs) -> list[str]

Generate lammps input block for NPT simulation. Support tracking box expension during NPT simulation. The simulation stops if \(abs(L - L0) / L0 > deform_limit\) in any of x, y, or z.

lmp_section_nph()
_lmp_section_dump(traj_freq: int, uid: str = None, single_frame=False) -> tuple[list[str]]
_lmp_section_run0(uid: str = None) -> tuple[list[str]]
_lmp_section_unfix(fixes: list[str] = [], dumps: list[str] = []) -> list[str]
_pbc_string(pbc: list = [1, 1, 1]) -> str

Convert pbc list to string. [1, 1, 0] -> "p p f". See https://docs.lammps.org/boundary.html

Acceptable values: 1, 0, p, f, s, m

_revise_input_pressure(press: Union[list[int], float, bool], pbc: list = [1, 1, 1], mask: list = [1, 1, 1], units: str = 'metal') -> list

Revise pressure string based on pbc and mask. This allows more flexible control of pressure setting, fllowing that: - Pressures only applied to the directions with pbc=1 and mask=1, regardless input press. - If press is a single value, this value is used to all directions. - Convert pressure unit from GPa to lammps unit based on choosen units (e.g. metal, real).

Parameters:

  • press (Union[list[int], float, bool]) –

    float/1x3 list of Pressure values in GPa. If a single value is provided, it is applied to all directions.

  • pbc (list[int], default: [1, 1, 1] ) –

    3x1 list of Periodic boundary conditions. Default [1, 1, 1]

  • mask (list[int], default: [1, 1, 1] ) –

    3x1 list of Mask for pressure. Default [1, 1, 1]. Mask to more control which directions is allowed to relax.

_press_string_minimize(press: list = [0.0, 0.0, 0.0]) -> str

Convert pressure list to lammps-style string. Example:

  • [0.0, 0.0, 0.0] -> 'x 0.0 y 0.0 z 0.0'
  • [None, 0.0, 0.0] -> 'y 0.0 z 0.0'
  • [None, None, None] -> ''
_press_string_md(press: list = [0.0, 0.0, 0.0], pdamp: int = 1000) -> str

Convert pressure list to lammps-style string. Example:

  • [0.0, 0.0, 0.0] -> 'x 0.0 y 0.0 z 0.0'
  • [None, 0.0, 0.0] -> 'y 0.0 z 0.0'
  • [None, None, None] -> error
process_lammps_argdict(argdict: dict) -> dict

LAMMPS argdict must be defined as a dictionary with 4 'top-level' keys: structure, optimize, md, extra. That form requirement is to be validated using LAMMPS args schema.

However, when generating lammps script, we only need the 'sub-level' keys. So, this function is to remove 'top-level' keys, and return 'sub-level' keys only to be used generate lammps script functions.

Parameters:

  • argdict (dict) –

    Dictionary of dicts of lammps arguments.

Returns:

  • dict ( dict ) –

    Processed lammps arguments.

tool

Functions:

init_alff_logger()

Initializing the logger

alff_info_text(packages=['ase', 'numpy', 'scipy', 'sevenn', 'phonopy', 'thkit', 'asext'])
alff_info_shorttext()
check_supported_calculator(calculator: str)

Check if the calculator is supported.

mk_struct_dir(pdict)

Create the directory name for the structure

validate