Skip to content

Commit 46f2223

Browse files
authored
Merge pull request #88 from Andrew-S-Rosen/mtk
Add IsotropicMTKNPT to `_md.py`
2 parents c75fb3a + b902145 commit 46f2223

2 files changed

Lines changed: 53 additions & 14 deletions

File tree

src/matcalc/_md.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from ase.md import Langevin
1010
from ase.md.andersen import Andersen
1111
from ase.md.bussi import Bussi
12+
from ase.md.nose_hoover_chain import IsotropicMTKNPT
1213
from ase.md.npt import NPT
1314
from ase.md.nptberendsen import Inhomogeneous_NPTBerendsen, NPTBerendsen
1415
from ase.md.nvtberendsen import NVTBerendsen
@@ -52,6 +53,7 @@ def __init__(
5253
"npt_nose_hoover",
5354
"npt_berendsen",
5455
"npt_inhomogeneous",
56+
"npt_isotropic_mtk",
5557
] = "nvt",
5658
temperature: int = 300,
5759
timestep: float = 1.0,
@@ -65,6 +67,10 @@ def __init__(
6567
pfactor: float = 75.0**2.0,
6668
external_stress: float | np.ndarray | None = None,
6769
compressibility_au: float | None = None,
70+
tchain: int = 3,
71+
pchain: int = 3,
72+
tloop: int = 1,
73+
ploop: int = 1,
6874
trajfile: Any = None,
6975
logfile: str | None = None,
7076
loginterval: int = 1,
@@ -83,20 +89,31 @@ def __init__(
8389
calculator (Calculator): The calculator used for energy, force, and stress evaluations.
8490
Default to the provided calculator.
8591
ensemble (str): Ensemble for MD simulation. Options include "nve", "nvt_langevin",
86-
"nvt_andersen", "nvt_bussi", "npt", "npt_berendsen", "npt_nose_hoover". Default to "nvt".
92+
"nvt_andersen", "nvt_bussi", "npt", "npt_berendsen", "npt_nose_hoover", "npt_mtk".
93+
Default to "nvt".
8794
temperature (int): Simulation temperature in Kelvin. Default to 300.
8895
timestep (float): Time step in femtoseconds. Default to 1.0.
8996
steps (int): Number of MD simulation steps. Default to 100.
9097
pressure (float): External pressure for NPT simulations (in eV/ų). Default to 1.01325 * units.bar.
9198
taut (float | None): Time constant for temperature coupling. If None, defaults to 100 * timestep * fs.
99+
For npt_isotropic_mtk, this is the time constant for temperature damping.
92100
taup (float | None): Time constant for pressure coupling. If None, defaults to 1000 * timestep * fs.
101+
For npt_isotropic_mtk, this is the time constant for pressure damping.
93102
friction (float): Friction coefficient for Langevin dynamics. Default to 1.0e-3.
94103
andersen_prob (float): Collision probability for Andersen thermostat. Default to 1.0e-2.
95104
ttime (float): Characteristic time scale for the thermostat in ASE units (fs). Default to 25.0.
96105
pfactor (float): Barostat differential equation constant. Default to 75.0**2.0.
97106
external_stress (float | np.ndarray | None): External stress applied to the system.
98107
If not provided, defaults to 0.0.
99108
compressibility_au (float | None): Material compressibility in ų/eV. Default to None.
109+
tchain (int): The number of thermostat variables in the Nose-Hoover thermostat. Default to 3.
110+
Only used by IsotropicMTKNPT.
111+
pchain (int): The number of barostat variables in the Nose-Hoover barostat. Default to 3.
112+
Only used by IsotropicMTKNPT.
113+
tloop (int): The number of sub-steps in thermostat integration. Default to 1.
114+
Only used by IsotropicMTKNPT.
115+
ploop (int): T The number of sub-steps in barostat integration. Default to 1.
116+
Only used by IsotropicMTKNPT.
100117
trajfile (Any): Trajectory object or file for storing simulation data. Default to None.
101118
logfile (str | None): Filename for simulation logs. Default to None.
102119
loginterval (int): Interval (in steps) for logging simulation data. Default to 1.
@@ -125,6 +142,10 @@ def __init__(
125142
self.pfactor = pfactor
126143
self.external_stress = external_stress
127144
self.compressibility_au = compressibility_au
145+
self.tchain = tchain
146+
self.pchain = pchain
147+
self.tloop = tloop
148+
self.ploop = ploop
128149
self.trajfile = trajfile
129150
self.logfile = logfile
130151
self.loginterval = loginterval
@@ -266,11 +287,30 @@ def _initialize_md(self, atoms: Atoms) -> Any:
266287
loginterval=self.loginterval,
267288
append_trajectory=self.append_trajectory,
268289
)
290+
elif self.ensemble.lower() == "npt_isotropic_mtk":
291+
md = IsotropicMTKNPT(
292+
atoms,
293+
timestep=timestep_fs,
294+
temperature_K=self.temperature,
295+
pressure_au=self.pressure,
296+
tdamp=taut,
297+
pdamp=taup,
298+
tchain=self.tchain,
299+
pchain=self.pchain,
300+
tloop=self.tloop,
301+
ploop=self.ploop,
302+
trajectory=self.trajfile,
303+
logfile=self.logfile,
304+
loginterval=self.loginterval,
305+
append_trajectory=self.append_trajectory,
306+
)
307+
269308
else:
270309
raise ValueError(
271310
"The specified ensemble is not supported, choose from 'nve', 'nvt',"
272311
" 'nvt_nose_hoover', 'nvt_berendsen', 'nvt_langevin', 'nvt_andersen',"
273-
" 'nvt_bussi', 'npt', 'npt_nose_hoover', 'npt_berendsen', 'npt_inhomogeneous'."
312+
" 'nvt_bussi', 'npt', 'npt_nose_hoover', 'npt_berendsen', 'npt_inhomogeneous',"
313+
" 'npt_isotropic_mtk'."
274314
)
275315
return md
276316

tests/test_md.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@
1919
@pytest.mark.parametrize(
2020
("ensemble", "expected_energy"),
2121
[
22-
("nve", -10.74606),
23-
("nvt", -10.81289),
24-
("nvt_berendsen", -10.73112),
25-
("nvt_langevin", -10.78238),
26-
("nvt_andersen", -10.82750),
27-
("nvt_bussi", -10.77756),
28-
("npt_inhomogeneous", -10.74737),
29-
("npt_berendsen", -10.74714),
30-
("npt_nose_hoover", -10.86120),
22+
("nve", -10.839367595419139),
23+
("nvt", -10.752140577997002),
24+
("nvt_berendsen", -10.79344712397928),
25+
("nvt_langevin", -10.719885845311552),
26+
("nvt_andersen", -10.838280482248559),
27+
("nvt_bussi", -10.83345229703825),
28+
("npt_inhomogeneous", -10.778117238180538),
29+
("npt_berendsen", -10.797141692994748),
30+
("npt_nose_hoover", -10.773028687488921),
31+
("npt_isotropic_mtk", -10.817933454243002),
3132
],
3233
)
3334
def test_md_calc(
@@ -46,8 +47,6 @@ def test_md_calc(
4647
calculator=matpes_calculator,
4748
ensemble=ensemble,
4849
temperature=300,
49-
taut=0.1,
50-
taup=0.1,
5150
steps=10,
5251
frames=5,
5352
compressibility_au=1,
@@ -63,7 +62,7 @@ def test_md_calc(
6362
assert "kinetic_energy" in results
6463
assert "total_energy" in results
6564

66-
assert results["total_energy"] == pytest.approx(expected_energy, rel=1e-1)
65+
assert results["total_energy"] == pytest.approx(expected_energy, rel=1e-2)
6766

6867
energies = np.array(results["trajectory"].total_energies)
6968

0 commit comments

Comments
 (0)