|
26 | 26 | from ase.md.verlet import VelocityVerlet |
27 | 27 |
|
28 | 28 | from fairchem.core.components.calculate import ( |
| 29 | + BerendsenNPT, |
29 | 30 | BussiThermostat, |
30 | 31 | LangevinThermostat, |
31 | 32 | MDRunner, |
@@ -148,8 +149,15 @@ def test_md_correctness_vs_ase(self, cu_atoms, results_dir): |
148 | 149 | NoseHooverNVT(temperature_K=300.0, tdamp_fs=25.0), |
149 | 150 | BussiThermostat(temperature_K=300.0, taut_fs=25.0), |
150 | 151 | LangevinThermostat(temperature_K=300.0, friction_per_fs=0.01), |
| 152 | + BerendsenNPT( |
| 153 | + temperature_K=300.0, |
| 154 | + pressure_bar=1.0, |
| 155 | + taut_fs=500.0, |
| 156 | + taup_fs=1000.0, |
| 157 | + compressibility_bar=1.0 / 140e9, |
| 158 | + ), |
151 | 159 | ], |
152 | | - ids=["VelocityVerlet", "NoseHoover", "Bussi", "Langevin"], |
| 160 | + ids=["VelocityVerlet", "NoseHoover", "Bussi", "Langevin", "BerendsenNPT"], |
153 | 161 | ) |
154 | 162 | def test_checkpoint_resume(self, cu_atoms, results_dir, thermostat): |
155 | 163 | """ |
@@ -333,3 +341,38 @@ def test_stopfair_graceful_stop(self, cu_atoms, results_dir): |
333 | 341 |
|
334 | 342 | traj_df = pd.read_parquet(results["trajectory_file"]) |
335 | 343 | assert list(traj_df["step"]) == [0, 10, 20] |
| 344 | + |
| 345 | + def test_npt_cell_changes(self, cu_atoms, results_dir): |
| 346 | + """ |
| 347 | + Verify that NPT simulation changes the cell volume. |
| 348 | + """ |
| 349 | + md_results_dir = results_dir / "results" |
| 350 | + md_results_dir.mkdir() |
| 351 | + |
| 352 | + atoms = cu_atoms.copy() |
| 353 | + initial_volume = atoms.get_volume() |
| 354 | + |
| 355 | + # Use a large pressure to drive a noticeable volume change |
| 356 | + thermostat = BerendsenNPT( |
| 357 | + temperature_K=300.0, |
| 358 | + pressure_bar=1e5, |
| 359 | + taut_fs=100.0, |
| 360 | + taup_fs=100.0, |
| 361 | + compressibility_bar=1.0 / 140e9, |
| 362 | + ) |
| 363 | + |
| 364 | + runner = MDRunner( |
| 365 | + calculator=EMT(), |
| 366 | + atoms=atoms, |
| 367 | + thermostat=thermostat, |
| 368 | + timestep_fs=1.0, |
| 369 | + steps=200, |
| 370 | + trajectory_interval=50, |
| 371 | + log_interval=50, |
| 372 | + trajectory_writer=partial(ParquetTrajectoryWriter, flush_interval=1000), |
| 373 | + ) |
| 374 | + runner._job_config = _create_mock_job_config(str(md_results_dir)) |
| 375 | + runner.calculate(job_num=0, num_jobs=1) |
| 376 | + |
| 377 | + final_volume = atoms.get_volume() |
| 378 | + assert initial_volume != pytest.approx(final_volume, rel=1e-6) |
0 commit comments