From 4ad326270d846298fc757976e5093e353c897d8e Mon Sep 17 00:00:00 2001 From: Letian88 Date: Fri, 3 Jul 2026 09:15:49 +0800 Subject: [PATCH 1/2] fix(abacus): use --config flag for phonopy 4.1.0 load mode compatibility phonopy 4.1.0 ignores positional conf file arguments when in 'load mode' (triggered by phonopy_disp.yaml). This caused band.yaml/mesh.yaml to not be generated during the Post step for ABACUS phonon and gruneisen properties. Fix: pass band.conf explicitly via --config flag, which phonopy 4.1.0 correctly reads as a configuration file even in load mode. Tested with Cu FCC (ABACUS DFT, 2x2x2 supercell): - phonon: band.yaml + band.dat + mesh.yaml generated successfully - gruneisen: FORCE_CONSTANTS + mesh.yaml (3 volumes) generated successfully --- apex/core/property/Gruneisen.py | 2 +- apex/core/property/Phonon.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apex/core/property/Gruneisen.py b/apex/core/property/Gruneisen.py index 2bf0462d..f4842f5c 100644 --- a/apex/core/property/Gruneisen.py +++ b/apex/core/property/Gruneisen.py @@ -963,7 +963,7 @@ def _ensure_abacus_volume_outputs( if not os.path.isfile("FORCE_CONSTANTS"): raise FileNotFoundError(f"FORCE_CONSTANTS was not created in {helper_dir}") if not os.path.isfile("mesh.yaml"): - subprocess.check_call(Phonon.phonopy_command("band.conf"), shell=True) + subprocess.check_call(Phonon.phonopy_command("phonopy_disp.yaml --config band.conf"), shell=True) self._write_band_dat() finally: os.chdir(cwd) diff --git a/apex/core/property/Phonon.py b/apex/core/property/Phonon.py index 1951b4f2..f9e317ee 100644 --- a/apex/core/property/Phonon.py +++ b/apex/core/property/Phonon.py @@ -622,7 +622,7 @@ def _compute_lower(self, output_file, all_tasks, all_res): if not os.path.exists("FORCE_SETS"): raise FileNotFoundError("FORCE_SETS was not created") print('FORCE_SETS is created') - subprocess.check_call(self.phonopy_command("band.conf"), shell=True) + subprocess.check_call(self.phonopy_command("phonopy_disp.yaml --config band.conf"), shell=True) self.write_band_dat() elif self.inter_param["type"] == 'vasp': From cbac2a9e93a8c73d9b440d806d39a1361de052b3 Mon Sep 17 00:00:00 2001 From: letian Date: Tue, 7 Jul 2026 17:01:59 +0800 Subject: [PATCH 2/2] test: update phonon/gruneisen mocks for --config phonopy command Align unit tests with the phonopy 4.1.0 load-mode fix that passes band.conf via --config instead of a positional argument. Co-authored-by: Cursor --- tests/test_gruneisen.py | 9 ++++++--- tests/test_phonon.py | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/test_gruneisen.py b/tests/test_gruneisen.py index 0d1ad82d..d6729a8c 100644 --- a/tests/test_gruneisen.py +++ b/tests/test_gruneisen.py @@ -408,7 +408,7 @@ def fake_check_call(command, shell): Path("FORCE_SETS").write_text("fake force sets\n") elif command == Phonon.phonopy_setup_command("phonopy_disp.yaml --writefc"): Path("FORCE_CONSTANTS").write_text("fake force constants\n") - elif command == Phonon.phonopy_command("band.conf"): + elif command == Phonon.phonopy_command("phonopy_disp.yaml --config band.conf"): strain = loadfn("volume.json")["strain"] if strain < 0: frequencies = [4.2, 8.4] @@ -459,8 +459,11 @@ def fake_run(command, stdout, stderr, text): ]), 3, ) - self.assertEqual(len([cmd for _, cmd in calls if cmd == Phonon.phonopy_command("band.conf")]), 3) - self.assertFalse(any(cmd == "phonopy band.conf --abacus" for _, cmd in calls)) + self.assertEqual( + len([cmd for _, cmd in calls if cmd == Phonon.phonopy_command("phonopy_disp.yaml --config band.conf")]), + 3, + ) + self.assertFalse(any(cmd == "phonopy phonopy_disp.yaml --config band.conf --abacus" for _, cmd in calls)) self.assertTrue((work_dir / "volume.000000" / "mesh.yaml").is_file()) self.assertTrue((work_dir / "volume.000001" / "band.dat").is_file()) self.assertTrue("Temperature(K) SumGammaCv Sign" in ptr) diff --git a/tests/test_phonon.py b/tests/test_phonon.py index b817df5e..b28415e8 100644 --- a/tests/test_phonon.py +++ b/tests/test_phonon.py @@ -340,7 +340,7 @@ def fake_check_call(command, shell): calls.append(command) if command.startswith(Phonon.phonopy_setup_command("-f")): Path("FORCE_SETS").write_text("fake force sets\n") - elif command == Phonon.phonopy_command("band.conf"): + elif command == Phonon.phonopy_command("phonopy_disp.yaml --config band.conf"): Path("band.yaml").write_text("phonon: []\n") try: @@ -349,8 +349,8 @@ def fake_check_call(command, shell): patch.object(Phonon, "write_band_dat", side_effect=self._write_band_dat_for_compute): phonon._compute_lower(str(work_dir / "result.json"), [str(task_dir)], []) self.assertEqual(calls[0], Phonon.phonopy_setup_command("-f task.0*/OUT.ABACUS/running_scf.log")) - self.assertEqual(calls[1], Phonon.phonopy_command("band.conf")) - self.assertFalse(any("--abacus" in command and command.startswith("phonopy band.conf") for command in calls)) + self.assertEqual(calls[1], Phonon.phonopy_command("phonopy_disp.yaml --config band.conf")) + self.assertFalse(any("--abacus" in command and "band.conf" in command for command in calls)) finally: shutil.rmtree(work_dir, ignore_errors=True)