Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion docs/dev/forcefields.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ There is both an `ase` module in `atomate2`, based around general `ase` `Calcula

The `ase` module should be used to manage high-level tasks, such as geometry optimization, molecular dynamics, and nudged elastic band. Any further developments to these tools in `ase` should also warrant updates in this module in `atomate2`. For example, when `ase` rolled out the `MTKNPT` NPT MD barostat as a replacement for the default barostat, this was also made the default in `atomate2`.

The `forcefields` library should be used to develop concrete implementations of workflows, e.g., harmonic phonon, Grüneisen parameter, ApproxNEB.
The `forcefields` library should be used to develop concrete implementations of workflows, e.g., harmonic phonon, Grüneisen parameter, [ApproxNEB](https://doi.org/10.1063/1.4960790).

## Dependency Chaos

Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/abinit/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import jobflow
from jobflow import Maker, Response, job
from pymatgen.util.due import Doi, due

from atomate2 import SETTINGS
from atomate2.abinit.files import write_abinit_input_set
Expand Down Expand Up @@ -98,6 +99,7 @@ def setup_job(
)


@due.dcite(Doi("10.1063/5.028827"), description="Most recent Abinit paper")
@dataclass
class BaseAbinitMaker(Maker):
"""
Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/aims/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from jobflow import Maker, Response, job
from monty.serialization import dumpfn
from pymatgen.io.aims.sets.base import AimsInputGenerator
from pymatgen.util.due import Doi, due

from atomate2 import SETTINGS
from atomate2.aims.files import (
Expand Down Expand Up @@ -40,6 +41,7 @@
_FILES_TO_ZIP = _INPUT_FILES + _OUTPUT_FILES


@due.dcite(Doi("10.1016/j.cpc.2009.06.022"), description="FHI-AIMS")
@dataclass
class BaseAimsMaker(Maker):
"""
Expand Down
4 changes: 4 additions & 0 deletions src/atomate2/ase/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from jobflow import Maker, job
from pymatgen.core import Molecule, Structure
from pymatgen.io.ase import AseAtomsAdaptor
from pymatgen.util.due import Doi, due

from atomate2.ase.schemas import AseResult, AseTaskDoc
from atomate2.ase.utils import AseRelaxer
Expand All @@ -28,6 +29,9 @@
_ASE_DATA_OBJECTS = ["trajectory"]


@due.dcite(
Doi("10.1088/1361-648X/aa680e"), description="Atomic simulation environment."
)
@dataclass
class AseMaker(Maker, ABC):
"""
Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/common/flows/approx_neb.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from emmet.core.mobility.migrationgraph import MigrationGraphDoc
from jobflow import Flow, Maker, OnMissing
from pymatgen.util.due import Doi, due

from atomate2.common.jobs.approx_neb import (
collate_images_single_hop,
Expand All @@ -25,6 +26,7 @@
from pymatgen.util.typing import CompositionLike


@due.dcite(Doi("https://doi.org/10.1063/1.4960790"), description="ApproxNEB")
@dataclass
class CommonApproxNebMaker(Maker):
"""Run an ApproxNEB workflow.
Expand Down
8 changes: 8 additions & 0 deletions src/atomate2/cp2k/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
)
from pymatgen.electronic_structure.dos import DOS, CompleteDos, Dos
from pymatgen.io.common import VolumetricData
from pymatgen.util.due import Doi, due

from atomate2 import SETTINGS
from atomate2.common.files import gzip_files, gzip_output_folder
Expand Down Expand Up @@ -85,6 +86,13 @@ def make(structure):
return job(method, data=_DATA_OBJECTS, output_schema=TaskDocument)


@due.dcite(
Doi("10.1063/5.0007045"),
description=(
"CP2K review - ensure you cite all references "
'in the "R E F E R E N C E S" section of the CP2K output'
),
)
@dataclass
class BaseCp2kMaker(Maker):
"""
Expand Down
31 changes: 22 additions & 9 deletions src/atomate2/forcefields/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
from collections.abc import Callable, Generator
from typing import Any

try:
from torch import dtype as torch_dtype
except ImportError:
torch_dtype = str

from ase.calculators.calculator import Calculator

from atomate2.ase.schemas import AseResult
Expand Down Expand Up @@ -229,7 +234,9 @@ def ase_calculator_name(self) -> str:


def ase_calculator(
calculator_meta: str | MLFF | dict, **kwargs: Any
calculator_meta: str | MLFF | dict,
default_dtype: str | torch_dtype | None = None,
**kwargs: Any,
) -> Calculator | None:
"""
Create an ASE calculator from a given set of metadata.
Expand All @@ -246,7 +253,7 @@ def ase_calculator(
"@callable": "CHGNetCalculator"
}
```
args : optional args to pass to a calculator
default_dtype (str or pytorch dtype) : optional pytorch dtype to use if applicable
kwargs : optional kwargs to pass to a calculator

Returns
Expand Down Expand Up @@ -310,6 +317,9 @@ def ase_calculator(
)
matgl.config.BACKEND = "PYG"

if default_dtype is not None:
matgl.set_default_dtype(default_dtype)

matgl_calc = getattr(
import_module(f"matgl.ext._ase_{matgl.config.BACKEND.lower()}"),
"PESCalculator",
Expand All @@ -328,6 +338,7 @@ def ase_calculator(
calculator = MACECalculator(
model_paths=model_path,
device=device,
default_dtype=default_dtype or "",
**kwargs,
)

Expand All @@ -345,18 +356,20 @@ def ase_calculator(
"damping": "bj",
"xc": "pbe",
"cutoff": 40.0 * Bohr,
"dtype": kwargs.get(
"default_dtype", torch.get_default_dtype()
),
"dtype": default_dtype or torch.get_default_dtype(),
}
for k, v in default_d3_kwargs.items():
if k not in kwargs:
kwargs[k] = v
kwargs.update(
{
k: v
for k, v in default_d3_kwargs.items()
if k not in kwargs
}
)

d3_calc = TorchDFTD3Calculator(device=device, **kwargs)
calculator = SumCalculator([calculator, d3_calc])
else:
calculator = mace_mp(**kwargs)
calculator = mace_mp(default_dtype=default_dtype or "", **kwargs)

case MLFF.Nequip | MLFF.Allegro:
from nequip.integrations.ase import NequIPCalculator
Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/jdftx/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
BandStructure,
BandStructureSymmLine,
)
from pymatgen.util.due import Doi, due

from atomate2.jdftx.files import write_jdftx_input_set
from atomate2.jdftx.run import run_jdftx, should_stop_children
Expand Down Expand Up @@ -73,6 +74,7 @@ def jdftx_job(method: Callable) -> job:
return job(method, data=_DATA_OBJECTS, output_schema=TaskDoc)


@due.dcite(Doi("10.1016/j.softx.2017.10.006"), description="JDFTx")
@dataclass
class BaseJdftxMaker(Maker):
"""
Expand Down
8 changes: 8 additions & 0 deletions src/atomate2/lobster/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from pymatgen.electronic_structure.cohp import CompleteCohp
from pymatgen.electronic_structure.dos import LobsterCompleteDos
from pymatgen.io.lobster import Bandoverlaps, Icohplist, Lobsterin
from pymatgen.util.due import Doi, due

from atomate2 import SETTINGS
from atomate2.common.files import gzip_output_folder
Expand All @@ -27,6 +28,13 @@
_FILES_TO_ZIP = [*LOBSTEROUTPUT_FILES, "lobsterin", *VASP_OUTPUT_FILES]


@due.dcite(
Doi("https://doi.org/10.1002/jcc.26353"),
description=(
"Most recent LOBSTER paper. "
"Please cite the publications mentioned in the LOBSTER Terms of Use."
),
)
@dataclass
class LobsterMaker(Maker):
"""
Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/openff/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from openff.interchange.components._packmol import pack_box
from openff.toolkit import ForceField
from openff.units import unit
from pymatgen.util.due import Doi, due

from atomate2.openff.utils import create_mol_spec_list, merge_specs_by_name_and_smiles

Expand Down Expand Up @@ -56,6 +57,7 @@ def make(structure):
)


@due.dcite(Doi("10.1021/acs.jpcb.4c01558"), description="Open forcefield initiative")
@openff_job
def generate_interchange(
input_mol_specs: list[MoleculeSpec | dict],
Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/openmm/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from openmm.app import StateDataReporter
from openmm.unit import angstrom, kelvin, picoseconds
from pymatgen.core import Structure
from pymatgen.util.due import Doi, due

from atomate2.openmm.interchange import OpenMMInterchange
from atomate2.openmm.utils import (
Expand Down Expand Up @@ -113,6 +114,7 @@ def make(structure):
)


@due.dcite(Doi("10.1021/acs.jpcb.3c06662"), description="OpenMM 8")
@dataclass
class BaseOpenMMMaker(Maker):
"""Base class for OpenMM simulation makers.
Expand Down
2 changes: 2 additions & 0 deletions src/atomate2/torchsim/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import torch_sim as ts
from jobflow import Maker, Response, job
from pymatgen.core import Structure
from pymatgen.util.due import Doi, due
from torch_sim.autobatching import BinningAutoBatcher, InFlightAutoBatcher

from atomate2.torchsim.schema import (
Expand All @@ -38,6 +39,7 @@
from torch_sim.trajectory import TrajectoryReporter


@due.dcite(Doi("10.1088/3050-287X/ae1799"), description="TorchSim")
def torchsim_job(method: Callable) -> job:
"""Decorate the ``make`` method of TorchSim job makers.

Expand Down
5 changes: 5 additions & 0 deletions src/atomate2/vasp/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
)
from pymatgen.electronic_structure.dos import DOS, CompleteDos, Dos
from pymatgen.io.vasp import Chgcar, Locpot, Wavecar
from pymatgen.util.due import Doi, due

from atomate2 import SETTINGS
from atomate2.common.files import gzip_output_folder
Expand Down Expand Up @@ -165,6 +166,10 @@ def make(structure):
return job(method, data=_DATA_OBJECTS, output_schema=TaskDoc)


@due.dcite(Doi("10.1103/PhysRevB.47.558"), description="VASP: MD for metals")
@due.dcite(Doi("10.1103/PhysRevB.49.14251"), description="VASP: MD")
@due.dcite(Doi("10.1016/0927-0256(96)00008-0"), description="VASP: core algorithms")
@due.dcite(Doi("10.1103/PhysRevB.54.11169"), description="VASP: self-consistency")
@dataclass
class BaseVaspMaker(Maker):
"""
Expand Down
Loading