Skip to content

Commit 4f30bfa

Browse files
cote3804cote3804
andauthored
Move JDFTx sets from atomate2 to pymatgen (#4479)
* Addition of JDFTx set to pymatgen from atomate2. * None structure handling in input set generation --------- Signed-off-by: Cooper <[email protected]> Co-authored-by: cote3804 <[email protected]>
1 parent 38997ee commit 4f30bfa

File tree

3 files changed

+198
-0
lines changed

3 files changed

+198
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Default JDFTx settings for atomate2 calculations.
2+
### Functional ###
3+
elec-ex-corr: gga
4+
van-der-waals: D3
5+
6+
### Electronic Parameters ###
7+
elec-cutoff:
8+
Ecut: 20
9+
EcutRho: 100
10+
electronic-minimize:
11+
nIterations: 100
12+
energyDiffThreshold: 1.0e-07
13+
elec-smearing:
14+
smearingType: Fermi
15+
smearingWidth: 0.001
16+
# elec-initial-magnetization:
17+
# M: 0
18+
# constrain: False
19+
spintype: z-spin
20+
core-overlap-check: none
21+
converge-empty-states: True
22+
band-projection-params:
23+
ortho: True
24+
norm: False
25+
26+
### Lattice / Unit Cell ###
27+
latt-move-scale:
28+
s0: 0
29+
s1: 0
30+
s2: 0
31+
lattice-minimize:
32+
nIterations: 00
33+
symmetries: none
34+
#coulomb-interaction: slab 001
35+
#coords-type Lattice
36+
37+
### Solvation & Bias ###
38+
# fluid: LinearPCM
39+
# pcm-variant: CANDLE
40+
# fluid-solvent: H2O
41+
# fluid-cation:
42+
# name: Na+
43+
# concentration: 0.5
44+
# fluid-anion:
45+
# name: F-
46+
# concentration: 0.5
47+
48+
### Pseudopotential ###
49+
ion-species: GBRV_v1.5/$ID_pbe_v1.uspp
50+
51+
52+
### Output Files ###
53+
dump-name: jdftx.$VAR
54+
dump:
55+
- End:
56+
Dtot: True
57+
State: True
58+
BoundCharge: True
59+
Forces: True
60+
Ecomponents: True
61+
VfluidTot: True
62+
ElecDensity: True
63+
KEdensity: True
64+
EigStats: True
65+
BandEigs: True
66+
BandProjections: True
67+
DOS: True

src/pymatgen/io/jdftx/sets.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from __future__ import annotations
2+
3+
import os
4+
from pathlib import Path
5+
from typing import TYPE_CHECKING
6+
7+
from pymatgen.io.core import InputSet
8+
from pymatgen.io.jdftx.inputs import JDFTXInfile, JDFTXStructure
9+
10+
if TYPE_CHECKING:
11+
from pymatgen.core import Structure
12+
from pymatgen.util.typing import PathLike
13+
14+
FILE_NAMES = {"in": "init.in", "out": "jdftx.out"}
15+
16+
17+
class JdftxInputSet(InputSet):
18+
"""
19+
A class to represent a JDFTx input file as a JDFTx InputSet.
20+
21+
Parameters
22+
----------
23+
jdftxinput
24+
A JdftxInput object
25+
"""
26+
27+
def __init__(self, jdftxinput: JDFTXInfile, structure: Structure) -> None:
28+
self.structure = structure
29+
self.jdftxinput = jdftxinput
30+
31+
def write_input(
32+
self,
33+
directory: str | Path,
34+
infile: PathLike = FILE_NAMES["in"],
35+
make_dir: bool = True,
36+
overwrite: bool = True,
37+
) -> None:
38+
"""Write JDFTx input file to a directory.
39+
40+
Parameters
41+
----------
42+
directory
43+
Directory to write input files to.
44+
make_dir
45+
Whether to create the directory if it does not already exist.
46+
overwrite
47+
Whether to overwrite an input file if it already exists.
48+
"""
49+
directory = Path(directory)
50+
if make_dir:
51+
os.makedirs(directory, exist_ok=True)
52+
53+
if not overwrite and (directory / infile).exists():
54+
raise FileExistsError(f"{directory / infile} already exists.")
55+
jdftx_structure = JDFTXStructure(structure=self.structure)
56+
jdftxinput = condense_jdftxinputs(self.jdftxinput, jdftx_structure)
57+
58+
jdftxinput.write_file(filename=(directory / infile))
59+
60+
@staticmethod
61+
def from_file(
62+
file: PathLike,
63+
) -> JdftxInputSet:
64+
"""Load a set of JDFTx inputs from a filename.
65+
66+
Parameters
67+
----------
68+
directory
69+
Input file to read JDFTx inputs from.
70+
"""
71+
jdftxinput = JDFTXInfile.from_file(file)
72+
structure = jdftxinput.structure
73+
if structure is None:
74+
raise ValueError(f"Structure not defined in file {file}.")
75+
return JdftxInputSet(jdftxinput=jdftxinput, structure=structure)
76+
77+
78+
def condense_jdftxinputs(jdftxinput: JDFTXInfile, jdftxstructure: JDFTXStructure) -> JDFTXInfile:
79+
"""
80+
Combine JDFTXInfile and JDFTxStructure into complete JDFTXInfile.
81+
82+
Function combines a JDFTXInfile class with calculation
83+
settings and a JDFTxStructure that defines the structure
84+
into one JDFTXInfile instance.
85+
86+
Parameters
87+
----------
88+
jdftxinput: JDFTXInfile
89+
A JDFTXInfile object with calculation settings.
90+
91+
jdftxstructure: JDFTXStructure
92+
A JDFTXStructure object that defines the structure.
93+
94+
Returns
95+
-------
96+
JDFTXInfile
97+
A JDFTXInfile that includes the calculation
98+
parameters and input structure.
99+
"""
100+
# force Cartesian coordinates
101+
coords_type = jdftxinput.get("coords-type")
102+
return jdftxinput + JDFTXInfile.from_str(jdftxstructure.get_str(in_cart_coords=(coords_type == "Cartesian")))

tests/io/jdftx/test_sets.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Tests for JDFTx input sets."""
2+
3+
from __future__ import annotations
4+
5+
from pathlib import Path
6+
7+
from pymatgen.io.jdftx.inputs import JDFTXInfile
8+
from pymatgen.io.jdftx.sets import JdftxInputSet
9+
from pymatgen.util.testing import TEST_FILES_DIR
10+
11+
from .inputs_test_utils import assert_idential_jif, ex_infile1_fname
12+
13+
ex_files_dir = Path(TEST_FILES_DIR) / "io" / "jdftx" / "example_files"
14+
15+
16+
def test_jdftxinputset_from_directory():
17+
input_set = JdftxInputSet.from_file(ex_infile1_fname)
18+
jdftx_inputfile = JDFTXInfile.from_file(ex_infile1_fname)
19+
assert_idential_jif(input_set.jdftxinput, jdftx_inputfile)
20+
21+
22+
def test_jdftxinputset_write_file(tmp_path):
23+
jdftx_inputfile = JDFTXInfile.from_file(ex_infile1_fname)
24+
input_set = JdftxInputSet(jdftx_inputfile, jdftx_inputfile.structure)
25+
input_set.write_input(tmp_path, infile="test.in")
26+
written_file = tmp_path / "test.in"
27+
read_jdftx_inputfile = JDFTXInfile.from_file(written_file)
28+
assert written_file.exists()
29+
assert_idential_jif(read_jdftx_inputfile, jdftx_inputfile)

0 commit comments

Comments
 (0)