Skip to content
Open
Show file tree
Hide file tree
Changes from 200 commits
Commits
Show all changes
208 commits
Select commit Hold shift + click to select a range
d5b89c8
New branch to add in atomate2 flows for lammps. Added basic file stru…
vir-k01 Oct 24, 2024
243c071
Moved lammps invokation settings into common atomate2 settings object…
vir-k01 Oct 25, 2024
646719c
Removed unneccessary MPI settings from atomate2.SETTINGS. MPI options…
vir-k01 Oct 25, 2024
2e24f0a
redid taskdoc to get log files read. Have to pass dump file reading t…
vir-k01 Oct 25, 2024
1dd4db8
Fix input file name, modify template to account for more simulation p…
vir-k01 Oct 30, 2024
08989a0
Added helper function to convert dump to PMGTraj
vir-k01 Oct 31, 2024
06d5aab
Redid force_field setup, added correct _DATA_OBJECTS for jobstore, be…
vir-k01 Oct 31, 2024
6dea0f9
More expressive taskdoc, added ability to parse dump file into pmgtraj
vir-k01 Oct 31, 2024
454cfc1
Defined a BASE_SETTINGS object, base set now inherits lammps generato…
vir-k01 Oct 31, 2024
9a4d4f0
Merge pull request #2 from materialsproject/main
vir-k01 Nov 1, 2024
c1e670f
Redid trajectory reading into taskdoc with a new DumpConvertor class,…
vir-k01 Nov 1, 2024
c260a97
Fixed issue with filename to write out trajectory to disk when buildi…
vir-k01 Nov 2, 2024
ec3b7d0
Streamlined lammps input set settings, moved default settings and key…
vir-k01 Nov 2, 2024
af60b51
Added basic implementation for NVT and NPT sets
vir-k01 Nov 2, 2024
da7b087
Added ability to restart lammps run from prev_dir; added keys in sett…
vir-k01 Nov 4, 2024
ee94293
Fixed nvt and npt set initialization, accounted only for nose-hoover …
vir-k01 Nov 4, 2024
7550f5f
Only add raw_log_file and trajectory with metadata to jobstore
vir-k01 Nov 4, 2024
2630a52
Better management of settings keys in utils, account for random seed …
vir-k01 Nov 4, 2024
5ee8730
Fixed fallback data types for raw_log and thermo_log if files arent p…
vir-k01 Nov 4, 2024
fc0b845
Remove zipping dir for debugging purposes
vir-k01 Nov 4, 2024
36792eb
Relaxed force field input to through warning if not dict, redid logic…
vir-k01 Nov 4, 2024
af85468
Fix species variables in base set
vir-k01 Nov 4, 2024
4ecfec1
Redid logic for update_settings
vir-k01 Nov 5, 2024
2d86231
Added reudimentary sets for a custom lammps job based on a user provi…
vir-k01 Nov 5, 2024
277d98a
Added task state to TaskDoc, made task state and store traj option to…
vir-k01 Nov 8, 2024
eb9e910
Typo in StoreTrajectoryOption, added ValError exception when log file…
vir-k01 Nov 8, 2024
2ff7ecb
Fixed imports
vir-k01 Nov 8, 2024
2b10f7f
Fixed super init for base set from core sets, fixed update settings f…
vir-k01 Nov 8, 2024
92953bf
Better missing log file handling
vir-k01 Nov 8, 2024
02805f2
Add time delay to task doc reading (debug)
vir-k01 Nov 8, 2024
313d0c8
Account for "ERROR" tag being anywhere in log file, actual error in l…
vir-k01 Nov 8, 2024
d37b3f4
Missing subprocess.wait() added, removed time.sleep debugger
vir-k01 Nov 8, 2024
28e5049
More info in lammps error message
vir-k01 Nov 8, 2024
e89a1d5
Add in check if force_field is given as a string to ensure species is…
vir-k01 Nov 9, 2024
2bd2fad
bug in reading error from log
vir-k01 Nov 9, 2024
c1a28d0
Better defaults for friction factors, fixed bug in update_settings
vir-k01 Nov 9, 2024
092e524
Bug in update_settings
vir-k01 Nov 9, 2024
1dea27c
Problem with passing settings from core to base sets
vir-k01 Nov 9, 2024
d7e9e00
Another attempt at fixing passing kwargs from core to base sets
vir-k01 Nov 9, 2024
51358b4
Added option for boundary (periodic or otherwise) and dimensions of s…
vir-k01 Nov 9, 2024
95a245e
Made structure optional to make since a lammpsdata obj can also be pr…
vir-k01 Nov 11, 2024
386d460
Added neighbour list recalc line, needed to stabilize real simulations
vir-k01 Nov 11, 2024
4f920af
Cleaned up init logic a bit, kwargs now consistent with AseMDMaker, f…
vir-k01 Nov 11, 2024
a52ed77
Massive cleanup of core sets and makers, settings now internally cons…
vir-k01 Nov 11, 2024
3e71805
Merge pull request #3 from materialsproject/main
vir-k01 Nov 11, 2024
0f3906e
lintig
vir-k01 Nov 12, 2024
ca19673
Error with not having temperature and pressure as props of set, accou…
vir-k01 Nov 12, 2024
9d6808e
By default write trajectory parsed from dump as "trajectory{id}.traj"
vir-k01 Nov 12, 2024
a18a3c7
Option to now give force_field as input to either the input_set_gener…
vir-k01 Nov 13, 2024
44fb6cf
Add ability to take in openff interchange as input for FF and topolog…
vir-k01 Nov 13, 2024
92fe8c4
corrected logic when providing interchange as FF
vir-k01 Nov 15, 2024
bbf1167
New LammpsInterchange class to allow for serialization of Interchange…
vir-k01 Nov 15, 2024
b4bf075
Updated minimization template
vir-k01 Nov 15, 2024
f7081f3
Added warnings when user asks to store trajectory in jobstore, now de…
vir-k01 Nov 18, 2024
458a73b
Added more settings keys to templates, made file names consistent bet…
vir-k01 Nov 18, 2024
aabc1ee
Moved update_settings to be a part of BaseLammpsSet.
vir-k01 Nov 18, 2024
1ce3922
Removed print statement
vir-k01 Nov 18, 2024
1e33d11
Remove all extra attributes from BaseLammpsSet, use settings dict for…
vir-k01 Nov 19, 2024
5cfc4e3
Merge branch 'materialsproject:main' into lammps_flows
vir-k01 Nov 19, 2024
6fb4e34
Merge pull request #4 from materialsproject/main
vir-k01 Dec 2, 2024
f086b22
Now also parse dump files as text and add to taskdoc, might be easier…
vir-k01 Dec 3, 2024
ffc69f1
Now also take in a LammpsInputFile object as a template, super helpfu…
vir-k01 Dec 3, 2024
5138774
First iteration of adding tests for lammps flows.
vir-k01 Dec 3, 2024
88c51b4
Move the dealing with template type logic to pymatgen
vir-k01 Dec 3, 2024
fb458f4
Cleaned up tests and paths, removed some redundancies
vir-k01 Dec 3, 2024
fc2359e
Add warning if store trajectory is specified by user, gzip output dir…
vir-k01 Dec 3, 2024
4d372e2
Use io funcs from pmg to read in job's input files, changed trajector…
vir-k01 Dec 3, 2024
8a11622
Remove unnecessary lines about len(trajecotry) from job tests, added …
vir-k01 Dec 3, 2024
d1489d0
Linting and cleaned up doc strings
vir-k01 Dec 3, 2024
7abee64
Save parsed dump files to jobstore instead of taskdoc
vir-k01 Dec 3, 2024
786295c
typing; minor changes to dump convertor class (now takes in index to …
vir-k01 Dec 3, 2024
43c4b57
removed uncessary imports, fixed test with partial trajecotry
vir-k01 Dec 3, 2024
a92a575
Added flow for melt+quench+thermalize (standard for amorphous/glassy …
vir-k01 Dec 3, 2024
e642082
MASSIVE UPDATE
vir-k01 Dec 10, 2024
19080fa
Updated paths for tests
vir-k01 Dec 10, 2024
0d11119
Added CustomLammpsMaker, cleaned up comments
vir-k01 Dec 10, 2024
cbfa83f
Remove unneccesary settigns_files
vir-k01 Dec 10, 2024
7e85462
Added docstrings, cleaned up old util functions, fixed imports
vir-k01 Dec 10, 2024
0ba672e
Make customlammpsmaker more flexible, add kspace settings to input
vir-k01 Dec 10, 2024
5a230eb
Allow all types of inputs to customslammpsmaker to provide settings u…
vir-k01 Dec 10, 2024
ebe0598
Merge pull request #6 from materialsproject/main
vir-k01 Jan 6, 2025
96f7b90
Move inputsetgenerator to pmg
vir-k01 Jan 8, 2025
6034c03
Modified jobs and flows to now be consistent with LammpsSettings obj …
vir-k01 Jan 9, 2025
7307aad
Merge pull request #7 from materialsproject/main
vir-k01 Jan 28, 2025
6344446
better FF handling
vir-k01 Apr 19, 2025
727f480
Better FF handling
vir-k01 Apr 19, 2025
202b592
Synced sets and makers with Templated approached based on BaseLammpsS…
vir-k01 Apr 19, 2025
fffeaed
Merge pull request #8 from materialsproject/main
vir-k01 Apr 19, 2025
b3ebc9f
Added a tutorial notebook to show how to initialize and use the Lammp…
vir-k01 Apr 19, 2025
fe89fa9
Updated tutorial
vir-k01 Apr 19, 2025
81a8ab3
Updated notebook
vir-k01 Apr 19, 2025
f5842ab
Updated tests
vir-k01 Apr 19, 2025
6393d3c
Fixed typo in lammpsjob decorator; fixed logic in taskdoc
vir-k01 Apr 19, 2025
218e78a
Fixed typo in lammpsjob decorator; fixed logic in taskdoc
vir-k01 Apr 19, 2025
d9ecc91
Removed unecessary files
vir-k01 Apr 19, 2025
0f7d33c
remove comment
vir-k01 Apr 19, 2025
32ee9a2
fix bug of metadata going to jobstore
vir-k01 Apr 22, 2025
0d3d6f9
linting
vir-k01 Apr 22, 2025
dec10ed
Added maker for NVE jobs
vir-k01 Apr 22, 2025
e8e7073
Consolidate lammps run commands
vir-k01 Apr 22, 2025
e50d384
fix lammps mpi invokation
vir-k01 Apr 22, 2025
ffdc708
New branch to add in atomate2 flows for lammps. Added basic file stru…
vir-k01 Oct 24, 2024
80b16af
Moved lammps invokation settings into common atomate2 settings object…
vir-k01 Oct 25, 2024
64b124f
Removed unneccessary MPI settings from atomate2.SETTINGS. MPI options…
vir-k01 Oct 25, 2024
b52f01d
redid taskdoc to get log files read. Have to pass dump file reading t…
vir-k01 Oct 25, 2024
68eba60
Fix input file name, modify template to account for more simulation p…
vir-k01 Oct 30, 2024
a750e8e
Added helper function to convert dump to PMGTraj
vir-k01 Oct 31, 2024
d44fa8b
Redid force_field setup, added correct _DATA_OBJECTS for jobstore, be…
vir-k01 Oct 31, 2024
8939d5d
More expressive taskdoc, added ability to parse dump file into pmgtraj
vir-k01 Oct 31, 2024
226c2a1
Defined a BASE_SETTINGS object, base set now inherits lammps generato…
vir-k01 Oct 31, 2024
d43f30b
Redid trajectory reading into taskdoc with a new DumpConvertor class,…
vir-k01 Nov 1, 2024
5d59a11
Fixed issue with filename to write out trajectory to disk when buildi…
vir-k01 Nov 2, 2024
e4c70f6
Streamlined lammps input set settings, moved default settings and key…
vir-k01 Nov 2, 2024
e96ac01
Added basic implementation for NVT and NPT sets
vir-k01 Nov 2, 2024
5004337
Added ability to restart lammps run from prev_dir; added keys in sett…
vir-k01 Nov 4, 2024
ec91bd7
Fixed nvt and npt set initialization, accounted only for nose-hoover …
vir-k01 Nov 4, 2024
c8c51f1
Only add raw_log_file and trajectory with metadata to jobstore
vir-k01 Nov 4, 2024
1b66489
Better management of settings keys in utils, account for random seed …
vir-k01 Nov 4, 2024
6025a61
Fixed fallback data types for raw_log and thermo_log if files arent p…
vir-k01 Nov 4, 2024
02c3a81
Remove zipping dir for debugging purposes
vir-k01 Nov 4, 2024
91ab9c2
Relaxed force field input to through warning if not dict, redid logic…
vir-k01 Nov 4, 2024
057447f
Fix species variables in base set
vir-k01 Nov 4, 2024
2f3dc7f
Redid logic for update_settings
vir-k01 Nov 5, 2024
dc37da1
Added reudimentary sets for a custom lammps job based on a user provi…
vir-k01 Nov 5, 2024
1b7c747
Added task state to TaskDoc, made task state and store traj option to…
vir-k01 Nov 8, 2024
47eb43e
Typo in StoreTrajectoryOption, added ValError exception when log file…
vir-k01 Nov 8, 2024
d2f51f8
Fixed imports
vir-k01 Nov 8, 2024
f49c734
Fixed super init for base set from core sets, fixed update settings f…
vir-k01 Nov 8, 2024
037e297
Better missing log file handling
vir-k01 Nov 8, 2024
b658e9a
Add time delay to task doc reading (debug)
vir-k01 Nov 8, 2024
9df8e59
Account for "ERROR" tag being anywhere in log file, actual error in l…
vir-k01 Nov 8, 2024
9628687
Missing subprocess.wait() added, removed time.sleep debugger
vir-k01 Nov 8, 2024
2468a15
More info in lammps error message
vir-k01 Nov 8, 2024
928eac3
Add in check if force_field is given as a string to ensure species is…
vir-k01 Nov 9, 2024
9ecb1d5
bug in reading error from log
vir-k01 Nov 9, 2024
6ef17d2
Better defaults for friction factors, fixed bug in update_settings
vir-k01 Nov 9, 2024
5c1088b
Bug in update_settings
vir-k01 Nov 9, 2024
60d5c38
Problem with passing settings from core to base sets
vir-k01 Nov 9, 2024
41e9902
Another attempt at fixing passing kwargs from core to base sets
vir-k01 Nov 9, 2024
0948c4c
Added option for boundary (periodic or otherwise) and dimensions of s…
vir-k01 Nov 9, 2024
e49d24e
Made structure optional to make since a lammpsdata obj can also be pr…
vir-k01 Nov 11, 2024
dac0f39
Added neighbour list recalc line, needed to stabilize real simulations
vir-k01 Nov 11, 2024
b27e5bb
Cleaned up init logic a bit, kwargs now consistent with AseMDMaker, f…
vir-k01 Nov 11, 2024
d9390ff
Massive cleanup of core sets and makers, settings now internally cons…
vir-k01 Nov 11, 2024
b3008a1
lintig
vir-k01 Nov 12, 2024
5318b96
Error with not having temperature and pressure as props of set, accou…
vir-k01 Nov 12, 2024
1b6ba53
By default write trajectory parsed from dump as "trajectory{id}.traj"
vir-k01 Nov 12, 2024
a605eef
Option to now give force_field as input to either the input_set_gener…
vir-k01 Nov 13, 2024
017cb36
Add ability to take in openff interchange as input for FF and topolog…
vir-k01 Nov 13, 2024
abb33b2
corrected logic when providing interchange as FF
vir-k01 Nov 15, 2024
bbaf4d4
New LammpsInterchange class to allow for serialization of Interchange…
vir-k01 Nov 15, 2024
0bdf2b5
Updated minimization template
vir-k01 Nov 15, 2024
e01721a
Added warnings when user asks to store trajectory in jobstore, now de…
vir-k01 Nov 18, 2024
bfda7a7
Added more settings keys to templates, made file names consistent bet…
vir-k01 Nov 18, 2024
51c71d7
Moved update_settings to be a part of BaseLammpsSet.
vir-k01 Nov 18, 2024
79ee014
Removed print statement
vir-k01 Nov 18, 2024
dfec30e
Remove all extra attributes from BaseLammpsSet, use settings dict for…
vir-k01 Nov 19, 2024
22e8931
Now also parse dump files as text and add to taskdoc, might be easier…
vir-k01 Dec 3, 2024
b439c60
Now also take in a LammpsInputFile object as a template, super helpfu…
vir-k01 Dec 3, 2024
c8bc63f
First iteration of adding tests for lammps flows.
vir-k01 Dec 3, 2024
c13d838
Move the dealing with template type logic to pymatgen
vir-k01 Dec 3, 2024
80ffcd6
Cleaned up tests and paths, removed some redundancies
vir-k01 Dec 3, 2024
0a5abef
Add warning if store trajectory is specified by user, gzip output dir…
vir-k01 Dec 3, 2024
78a2ee8
Use io funcs from pmg to read in job's input files, changed trajector…
vir-k01 Dec 3, 2024
f71ef1f
Remove unnecessary lines about len(trajecotry) from job tests, added …
vir-k01 Dec 3, 2024
a71e062
Linting and cleaned up doc strings
vir-k01 Dec 3, 2024
6d3dece
Save parsed dump files to jobstore instead of taskdoc
vir-k01 Dec 3, 2024
688f804
typing; minor changes to dump convertor class (now takes in index to …
vir-k01 Dec 3, 2024
8b4e671
removed uncessary imports, fixed test with partial trajecotry
vir-k01 Dec 3, 2024
5c58ae8
Added flow for melt+quench+thermalize (standard for amorphous/glassy …
vir-k01 Dec 3, 2024
a2c1d14
MASSIVE UPDATE
vir-k01 Dec 10, 2024
682048a
Updated paths for tests
vir-k01 Dec 10, 2024
85defc6
Added CustomLammpsMaker, cleaned up comments
vir-k01 Dec 10, 2024
f395171
Remove unneccesary settigns_files
vir-k01 Dec 10, 2024
937d67d
Added docstrings, cleaned up old util functions, fixed imports
vir-k01 Dec 10, 2024
be1e42b
Make customlammpsmaker more flexible, add kspace settings to input
vir-k01 Dec 10, 2024
434b9f9
Allow all types of inputs to customslammpsmaker to provide settings u…
vir-k01 Dec 10, 2024
c32438e
Move inputsetgenerator to pmg
vir-k01 Jan 8, 2025
4429951
Modified jobs and flows to now be consistent with LammpsSettings obj …
vir-k01 Jan 9, 2025
afce9cf
better FF handling
vir-k01 Apr 19, 2025
cef5b32
Better FF handling
vir-k01 Apr 19, 2025
cd12b08
Synced sets and makers with Templated approached based on BaseLammpsS…
vir-k01 Apr 19, 2025
8829e3b
Added a tutorial notebook to show how to initialize and use the Lammp…
vir-k01 Apr 19, 2025
aa736fe
Updated tutorial
vir-k01 Apr 19, 2025
cc9c572
Updated notebook
vir-k01 Apr 19, 2025
1c186ea
Updated tests
vir-k01 Apr 19, 2025
c1490dd
Fixed typo in lammpsjob decorator; fixed logic in taskdoc
vir-k01 Apr 19, 2025
026997b
Fixed typo in lammpsjob decorator; fixed logic in taskdoc
vir-k01 Apr 19, 2025
36c5d50
Removed unecessary files
vir-k01 Apr 19, 2025
96b7a2a
remove comment
vir-k01 Apr 19, 2025
79929ce
fix bug of metadata going to jobstore
vir-k01 Apr 22, 2025
32c5cd7
linting
vir-k01 Apr 22, 2025
be9acd1
Added maker for NVE jobs
vir-k01 Apr 22, 2025
72746a7
Consolidate lammps run commands
vir-k01 Apr 22, 2025
c124f93
fix lammps mpi invokation
vir-k01 Apr 22, 2025
1893e5c
Merge branch 'lammps_flows_templated' of github.com:vir-k01/atomate2 …
vir-k01 Apr 22, 2025
05aea9e
fix mpirun/srun invokation
vir-k01 Apr 22, 2025
cd46e38
Fixed typo/formatting in tutorial
vir-k01 Apr 22, 2025
895ec9f
Post init fix in CustomLammpsMaker
vir-k01 Apr 29, 2025
855e27c
Ruff, added ability to parse additional files that might be produced …
vir-k01 Apr 29, 2025
6bc8b39
Made flows take in prev_dir to read restart files, npt_maker now gets…
vir-k01 May 6, 2025
353c2af
removed msonable requirement
vir-k01 May 6, 2025
15932a5
Now store the any output files with *.data fomrat in order to retain …
vir-k01 May 6, 2025
9c74fa3
moved all task doc settings out into taskdoc funcs, prev_dir can take…
vir-k01 May 6, 2025
27f8f7f
change return type to any
vir-k01 May 6, 2025
2ad291f
Merge pull request #9 from materialsproject/main
vir-k01 May 16, 2025
2714a30
Merge pull request #10 from materialsproject/main
vir-k01 Jun 3, 2025
4a43bfc
Merge pull request #11 from materialsproject/main
vir-k01 Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added src/atomate2/lammps/__init__.py
Empty file.
92 changes: 92 additions & 0 deletions src/atomate2/lammps/files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from pathlib import Path
from pymatgen.core import Structure, Molecule
from pymatgen.io.lammps.generators import BaseLammpsGenerator
from ase.io import read
from pymatgen.io.ase import AseAtomsAdaptor
from pymatgen.io.lammps.data import LammpsData, CombinedData
from pymatgen.core.trajectory import Trajectory as PmgTrajectory
from ase.io import Trajectory as AseTrajectory
from typing import Literal
from monty.serialization import dumpfn
from monty.json import MSONable
from emmet.core.vasp.calculation import StoreTrajectoryOption

def write_lammps_input_set(
data: Structure | LammpsData | CombinedData,
input_set_generator: BaseLammpsGenerator,
additional_data : LammpsData | CombinedData | None = None,
directory: str | Path = ".",
):
input_set = input_set_generator.get_input_set(data,
additional_data,
)
input_set.write_input(directory)


class DumpConvertor(MSONable):
'''
Class to convert LAMMPS dump files to pymatgen or ase Trajectory objects. Based on TrajectoryObserver from atomate2.ase.

args:
dumpfile : str
Path to the LAMMPS dump file
store_md_outputs : StoreTrajectoryOption
Option to store MD outputs in the Trajectory object
read_index : str | int
Index of the frame to read from the dump file (default is ':', i.e. read all frames).
Use an integer to read a specific frame (practical for large files).

'''
def __init__(self, dumpfile, store_md_outputs : StoreTrajectoryOption = StoreTrajectoryOption.NO, read_index: str | int = ':') -> None:
self.store_md_outputs = store_md_outputs
self.traj = read(dumpfile, index=read_index) if isinstance(read_index, str) else [read(dumpfile, index=read_index)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not entirely correct. In fact, if read_index containts an integer index in the form of a string (for example "1") read still returns a single Atoms object. I understand that this is a particular case, but it is still make the simple check with isinstance(read_index, str) potentially incorrect.

self.is_periodic = any(self.traj[0].pbc)
self.frame_properties_keys = ['forces', 'velocities']

def to_ase_trajectory(self, filename : str | None = None):
for idx, atoms in enumerate(self.traj):
with AseTrajectory(filename, 'a' if idx > 0 else 'w', atoms = atoms) as file: #check logic here
file.write()
return AseTrajectory(filename, 'r')

def to_pymatgen_trajectory(self, filename : str | None = None) -> PmgTrajectory:

species = AseAtomsAdaptor.get_structure(self.traj[0], cls = Structure if self.is_periodic else Molecule).species

frames = []
frame_properties = []

for atoms in self.traj:
if self.store_md_outputs == StoreTrajectoryOption.FULL:
frame_properties.append({key : getattr(atoms, f'get_{key}')() for key in self.frame_properties_keys})

if self.is_periodic:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One potential issue of this approach is that in case of a system in box but without PBC the size of the box will be lost if converted to a Molecule. Could that be a relevant information to preserve? Could it be better to always store a Structure keeping track of the PBC?

frames.append(Structure(lattice = atoms.get_cell(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the lattice also the case of partially periodic boundary conditions could be considered, if the information is properly parsed by ASE.
Why not using the pymatgen AseAtomsAdaptorinstead? This takes everything into account automatically

species = species,
coords = atoms.get_positions(),
coords_are_cartesian = True)
)
else:
frames.append(Molecule(species = species,
coords = atoms.get_positions(),
charge = atoms.get_charges(),
)
)
traj_method = 'from_structures' if self.is_periodic else 'from_molecules'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My experience with big trajectories is that allocating many structures is often impractical due to the time and memory required to allocate many big Structures. Porbably it would be more efficient to build the Trajectory object directly from the array of coordinates, without passing for the list of structures.

pmg_traj = getattr(PmgTrajectory, traj_method)(
frames,
frame_properties=frame_properties if frame_properties else None,
constant_lattice=False,
)

if filename:
dumpfn(pmg_traj, filename)

return pmg_traj

def save(self, filename : str | None = None, fmt : Literal["pmg", "ase"] = "pmg"):
filename = str(filename) if filename is not None else None
if fmt == "pmg" and filename:
return self.to_pymatgen_trajectory(filename=filename)
if fmt == "ase" and filename:
return self.to_ase_trajectory(filename=filename)
66 changes: 66 additions & 0 deletions src/atomate2/lammps/flows/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from dataclasses import dataclass, field

from jobflow import Flow, Maker
from pymatgen.core import Structure

from atomate2.lammps.jobs.base import BaseLammpsMaker
from atomate2.lammps.jobs.core import LammpsNVTMaker, LammpsNPTMaker

from copy import deepcopy

import warnings


@dataclass
class MeltQuenchThermalizeMaker(Maker):
# potentially remove and replace with single job
name: str = "melt-quench-thermalize"
melt_maker: BaseLammpsMaker = field(default_factory=LammpsNPTMaker)
quench_maker: BaseLammpsMaker = field(default_factory=LammpsNPTMaker)
thermalize_maker: BaseLammpsMaker = field(default_factory=LammpsNVTMaker)

def make(self, structure: Structure):
melt = self.melt_maker.make(structure)
quench = self.quench_maker.make(melt.output.structure)
thermalize = self.thermalize_maker.make(quench.output.structure)
return Flow([melt, quench, thermalize], name=self.name)

@classmethod
def from_temperature_steps(
cls,
start_temperature: float = 300,
melt_temperature: float = 3000,
quench_temperature: float = 300,
n_steps_melt: int = 10000,
n_steps_quench: int = 10000,
n_steps_thermalize: int = 10000,
npt_maker : LammpsNPTMaker = None,
nvt_maker : LammpsNVTMaker = None
) -> "MeltQuenchThermalizeMaker":
if nvt_maker is None:
warnings.warn("No NVT maker provided, using NPT maker for thermalize.")
if npt_maker is None:
raise ValueError("NPT maker must be provided.")

melt_maker = deepcopy(npt_maker)
melt_maker.name = "melt"
melt_maker.input_set_generator.update_settings({"start_temp" : start_temperature,
"end_temp": melt_temperature,
"nsteps" : n_steps_melt})

quench_maker = deepcopy(npt_maker)
quench_maker.name = "quench"
quench_maker.input_set_generator.update_settings({"start_temp" : melt_temperature,
"end_temp": quench_temperature,
"nsteps" : n_steps_quench})

thermalize_maker = deepcopy(nvt_maker) if nvt_maker else deepcopy(npt_maker)
thermalize_maker.name = "thermalize"
thermalize_maker.input_set_generator.update_settings({"start_temp" : quench_temperature,
"end_temp": quench_temperature,
"nsteps" : n_steps_thermalize})
return cls(
melt_maker=melt_maker,
quench_maker=quench_maker,
thermalize_maker=thermalize_maker,
)
4 changes: 4 additions & 0 deletions src/atomate2/lammps/jobs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Lammps job makers for atomate2."""

from .base import BaseLammpsMaker
from .core import CustomLammpsMaker, LammpsNPTMaker, LammpsNVTMaker, MinimizationMaker
148 changes: 148 additions & 0 deletions src/atomate2/lammps/jobs/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
"""Base job maker for LAMMPS calculations."""

import glob
import os
import warnings
from collections.abc import Callable
from dataclasses import dataclass, field
from pathlib import Path

from emmet.core.vasp.task_valid import TaskState
from jobflow import Maker, Response, job
from pymatgen.core import Structure
from pymatgen.io.lammps.generators import (
BaseLammpsSetGenerator,
CombinedData,
LammpsData,
)

from atomate2.common.files import gzip_files
from atomate2.lammps.files import write_lammps_input_set
from atomate2.lammps.run import run_lammps
from atomate2.lammps.schemas.task import LammpsTaskDocument, StoreTrajectoryOption

_DATA_OBJECTS: list[str] = [
"raw_log_file",
"inputs",
"trajectories",
"dump_files",
]

__all__ = ("BaseLammpsMaker", "lammps_job")


class LammpsRunError(Exception):
"""Custom exception for LAMMPS jobs."""

def __init__(self, message: str) -> None:
super().__init__(message)
self.message = message


def lammps_job(method: Callable) -> job:
"""Job decorator for LAMMPS jobs."""
return job(method, data=_DATA_OBJECTS, output_schema=LammpsTaskDocument)


@dataclass
class BaseLammpsMaker(Maker):
"""
Basic Maker class for LAMMPS jobs.

name: str
Name of the job
input_set_generator: BaseLammpsGenerator
Input set generator for the job, default is the BaseLammpsSetGenerator.
Check the sets module for more options on input kwargs.
write_input_set_kwargs: dict
Additional kwargs to write_lammps_input_set
run_lammps_kwargs: dict
Additional kwargs to run_lammps
task_document_kwargs: dict
Additional kwargs to TaskDocument.from_directory
write_additional_data: dict
Additional data to write to the job directory
"""

name: str = "Base LAMMPS job"
input_set_generator: BaseLammpsSetGenerator = field(
default_factory=BaseLammpsSetGenerator
)
force_field: str | dict | None = field(default=None)
write_input_set_kwargs: dict = field(default_factory=dict)
run_lammps_kwargs: dict = field(default_factory=dict)
task_document_kwargs: dict = field(default_factory=dict)
write_additional_data: LammpsData | CombinedData = field(default_factory=dict)

def __post_init__(self) -> None:
"""Post-initialization warnings for the job."""
if (
self.task_document_kwargs.get("store_trajectory", StoreTrajectoryOption.NO)
!= StoreTrajectoryOption.NO
):
warnings.warn(
"Trajectory data might be large, only store if absolutely necessary. \
Consider manually parsing the dump files instead.",
stacklevel=1,
)

if self.force_field:
self.input_set_generator.force_field = self.force_field

@lammps_job
def make(
self,
input_structure: Structure | Path | LammpsData = None,
prev_dir: Path = None,
) -> Response:
"""Run a LAMMPS calculation."""
if prev_dir:
restart_files = glob.glob(os.path.join(prev_dir, "*restart*"))
if len(restart_files) != 1:
raise FileNotFoundError(
"No/More than one restart file found in the previous directory. \
If present, it should have the extension '.restart'!"
)

self.input_set_generator.update_settings(
{"read_restart": os.path.join(prev_dir, restart_files[0])}
)

if isinstance(input_structure, Path):
input_structure = LammpsData.from_file(
input_structure,
atom_style=self.input_set_generator.settings.get("atom_style", "full"),
)

write_lammps_input_set(
data=input_structure,
input_set_generator=self.input_set_generator,
additional_data=self.write_additional_data,
**self.write_input_set_kwargs,
)

run_lammps(**self.run_lammps_kwargs)

task_doc = LammpsTaskDocument.from_directory(
os.getcwd(), task_label=self.name, **self.task_document_kwargs
)

if task_doc.state == TaskState.ERROR:
try:
error = ""
for index, line in enumerate(task_doc.raw_log_file.split("\n")):
if "ERROR" in line:
error = error.join(task_doc.raw_log_file.split("\n")[index:])
break
except ValueError:
error = "could not parse log file"
raise LammpsRunError(f"Task {task_doc.task_label} failed, error: {error}")

task_doc.composition = input_structure.composition
task_doc.reduced_formula = input_structure.composition.reduced_formula
task_doc.task_label = self.name
task_doc.inputs = self.input_set_generator.settings.dict

gzip_files(".")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may not be strictly necessary, but would it be easy to make something equivalent to what is done in VASP and some other code, where only lammps related files are zipped?

gzip_output_folder(

One downside of zipping everything inside the folder is that when running on a cluster also the queue files are zipped and the queueing system may not be able to write it anymore.

Anyway, this can also be done at a later stage


return Response(output=task_doc)
Loading