Source code for ai2_kit.tool.lammps
from typing import Optional
from ase.data import atomic_masses, atomic_numbers
import pandas as pd
import json
[docs]class LammpsTool:
"""
A tool for LAMMPS related operations.
"""
[docs] def analysis_density_convergence(self, in_file: str, out_file: Optional[str] = None,
debug=False, err=0.0005, col_name: str = 'density'):
"""
Select a frame by density from a property file.
:param in_file: input properties file, e.g. properties.out
:param out_file: output file to save the selected frame, if None, return the result
:param col_name: column name to select by, default is 'density'
:param debug: if True, return the average density for each frame
:param err: error threshold for convergence, default is 0.0005
:return: a dictionary with converged density and frames, or save to out_file
"""
with open(in_file, 'r') as f:
f.seek(1) # skip the leading '#'
df = pd.read_csv(f, delim_whitespace=True, header=0)
if col_name not in df.columns:
raise ValueError(f'Column {col_name} not found in {in_file}')
density = df[col_name]
avg_density = density.cumsum() / (df.index + 1)
converged_density = avg_density.iloc[-1]
converged_df = df[(density - converged_density).abs() < err]
result = {
'converged_density': converged_density,
'converged_frames': converged_df.index.tolist(),
}
if debug:
result['time'] = df['time'].tolist()
result['avg_density'] = avg_density.tolist()
if out_file:
with open(out_file, 'w') as f:
json.dump(result, f)
else:
return result
[docs] def gen_mass_map(self, atom_types: tuple, out_file = None):
"""
Generate a mass map for LAMMPS.
:param atom_types: tuple of atom types, e.g. ('C', 'H', 'O')
:return: LAMMPS mass map string
:param out_file: output file to save the mass map, if None, return the string
:return: mass map string, e.g.:
```
mass 1 12.011 # C
mass 2 1.008 # H
mass 3 15.999 # O
```
"""
mass_list = []
# lookup mass from ase
for i, atom_type in enumerate(atom_types, start=1):
atom_no = atomic_numbers[atom_type]
if atom_no is None:
raise ValueError(f'Unknown atom type: {atom_type}')
mass = atomic_masses[atom_no]
mass_list.append(f'mass {i:>4} {mass:>8} # {atom_type}')
mass_map = '\n'.join(mass_list)
if out_file:
with open(out_file, 'w') as f:
f.write(mass_map)
return mass_map