From 04833f3ca86de2d0528649ea87a8ae1c746e9a61 Mon Sep 17 00:00:00 2001 From: Alin Marin Elena Date: Sun, 26 May 2024 10:47:41 +0100 Subject: [PATCH] add option to write eigenvectors and extra info in bands, useful for visualisation, but we end up with bigger files --- README.md | 11 ++++++++-- janus_core/calculations/phonons.py | 18 ++++++++++++--- janus_core/cli/phonons.py | 17 ++++++++++++++- tests/test_phonons_cli.py | 35 ++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 073fe96f..7520bc38 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,14 @@ Calculate phonons with a 2x2x2 supercell, after geometry optimization (using the janus phonons --struct tests/data/NaCl.cif --supercell 2x2x2 --minimize --arch mace_mp --calc-kwargs "{'model' : 'small'}" ``` -This will save the Phonopy parameters, including displacements and force constants, to `NaCl-params.yml`, and the calculated band structure to `NaCl-auto-band.yml`, in addition to generating a log file, `phonons.log`, and summary of inputs, `phonons_summary.yml`. +This will save the Phonopy parameters, including displacements and force constants, to `NaCl-phonopy.yml` and `NaCl-force\_constants.hdf5`, in addition to generating a log file, `phonons.log`, and summary of inputs, `phonons_summary.yml`. +Additionaly, to calculate band structure and generate `NaCl-auto-bands.yml` use: + +```shell +janus phonons --struct tests/data/NaCl.cif --supercell 2x2x2 --minimize --arch mace_mp --calc-kwargs "{'model' : 'small'}" +``` +If you need eigenvectors and group velocities written add `--write-full` option. Will generate a much bigger bands file but can be +used to visualise phonon modes. Further calculations, including thermal properties, DOS, and PDOS, can also be calculated (using a 2x3x4 supercell): @@ -212,7 +219,7 @@ Further calculations, including thermal properties, DOS, and PDOS, can also be c janus phonons --struct tests/data/NaCl.cif --supercell 2x3x4 --dos --pdos --thermal --temp-start 0 --temp-end 300 --temp-step 50 ``` -This will create additional output files: `NaCl-cv.dat` for the thermal properties (heat capacity, entropy, and free energy) between 0K and 300K, `NaCl-dos.dat` for the DOS, and `NaCl-pdos.dat` for the PDOS. +This will create additional output files: `NaCl-thermal.dat` for the thermal properties (heat capacity, entropy, and free energy) between 0K and 300K, `NaCl-dos.dat` for the DOS, and `NaCl-pdos.dat` for the PDOS. For all options, run `janus phonons --help`. diff --git a/janus_core/calculations/phonons.py b/janus_core/calculations/phonons.py index 7283922f..5d81a6ab 100644 --- a/janus_core/calculations/phonons.py +++ b/janus_core/calculations/phonons.py @@ -44,8 +44,11 @@ class Phonons: # pylint: disable=too-many-instance-attributes Whether to plot various graphs as band stuctures, dos/pdos in svg. Default is False. symmetrize : bool - Whether to symmetrize force constants after cauclation. + Whether to symmetrize force constants after calculation. Default is False. + write_full : bool + Whether to maximize information written in various output files. + Default is True. minimize_kwargs : Optional[dict[str, Any]] Keyword arguments to pass to geometry optimizer. Default is {}. file_prefix : Optional[PathLike] @@ -65,6 +68,7 @@ class Phonons: # pylint: disable=too-many-instance-attributes """ def __init__( # pylint: disable=too-many-arguments + # pylint: disable=too-many-locals self, struct: Atoms, struct_name: Optional[str] = None, @@ -77,6 +81,7 @@ def __init__( # pylint: disable=too-many-arguments hdf5: bool = True, plot_to_file: bool = False, symmetrize: bool = False, + write_full: bool = True, minimize_kwargs: Optional[dict[str, Any]] = None, file_prefix: Optional[PathLike] = None, log_kwargs: Optional[dict[str, Any]] = None, @@ -110,8 +115,11 @@ def __init__( # pylint: disable=too-many-arguments Whether to plot various graphs as band stuctures, dos/pdos in svg. Default is False. symmetrize : bool - Whether to symmetrize force constants after cauclation. + Whether to symmetrize force constants after calculations. Default is False. + write_full : bool + Whether to maximize information written in various output files. + Default is True. minimize_kwargs : Optional[dict[str, Any]] Keyword arguments to pass to geometry optimizer. Default is {}. file_prefix : Optional[PathLike] @@ -149,6 +157,7 @@ def __init__( # pylint: disable=too-many-arguments self.hdf5 = hdf5 self.plot_to_file = plot_to_file self.symmetrize = symmetrize + self.write_full = write_full if not self.struct.calc: raise ValueError("Please attach a calculator to `struct`.") @@ -265,7 +274,10 @@ def write_band_structure( bands_file = self._set_filename("auto_bands.yml", bands_file) self.results["phonon"].auto_band_structure( - write_yaml=write_bands, filename=bands_file + write_yaml=write_bands, + filename=bands_file, + with_eigenvectors=self.write_full, + with_group_velocities=self.write_full, ) if self.plot_to_file: bplt = self.results["phonon"].plot_band_structure() diff --git a/janus_core/cli/phonons.py b/janus_core/cli/phonons.py index 8697bb6d..e0bab664 100644 --- a/janus_core/cli/phonons.py +++ b/janus_core/cli/phonons.py @@ -96,6 +96,17 @@ def phonons( symmetrize: Annotated[ bool, Option(help="Whether to symmetrize force constants.") ] = False, + write_full: Annotated[ + bool, + Option( + help=( + """ + Whether to maximize the amount of information written + in various output files. + """ + ), + ), + ] = True, fmax: Annotated[ float, Option(help="Maximum force for optimization convergence.") ] = 0.1, @@ -160,6 +171,9 @@ def phonons( Whether to minimize structure before calculations. Default is False. symmetrize : bool Whether to symmetrize force constants. Default is False. + write_full : bool + Whether to maximize information written in various output files. + Default is True. fmax : float Set force convergence criteria for optimizer in units eV/Å. Default is 0.1. @@ -235,8 +249,9 @@ def phonons( "file_prefix": file_prefix, "log_kwargs": log_kwargs, "hdf5": hdf5, - "symmetrize": symmetrize, "plot_to_file": plot_to_file, + "symmetrize": symmetrize, + "write_full": write_full, } # Store inputs for yaml summary diff --git a/tests/test_phonons_cli.py b/tests/test_phonons_cli.py index bb781fe8..2aba2f01 100644 --- a/tests/test_phonons_cli.py +++ b/tests/test_phonons_cli.py @@ -20,8 +20,8 @@ def test_help(): assert "Usage: janus phonons [OPTIONS]" in result.stdout -def test_phonons(tmp_path): - """Test calculating phonons.""" +def test_bands(tmp_path): + """Test calculating force constants and bands.""" log_path = tmp_path / "test.log" summary_path = tmp_path / "summary.yml" phonon_results = tmp_path / "NaCl-phonopy.yml" @@ -46,6 +46,34 @@ def test_phonons(tmp_path): assert autoband_results.exists() +def test_bands_simple(tmp_path): + """Test calculating force constants and reduced bands information.""" + log_path = tmp_path / "test.log" + summary_path = tmp_path / "summary.yml" + autoband_results = tmp_path / "NaCl-auto_bands.yml" + result = runner.invoke( + app, + [ + "phonons", + "--struct", + DATA_PATH / "NaCl.cif", + "--file-prefix", + tmp_path / "NaCl", + "--log", + log_path, + "--summary", + summary_path, + "--band", + "--no-write-full", + ], + ) + assert result.exit_code == 0 + assert autoband_results.exists() + with open(autoband_results, encoding="utf8") as file: + bands = yaml.safe_load(file) + assert "eigenvector" not in bands["phonon"][0]["band"][0].keys() + + def test_hdf5(tmp_path): """Test calculating phonons.""" log_path = tmp_path / "test.log" @@ -184,6 +212,9 @@ def test_plot(tmp_path): assert autoband_results.exists() for svg in svgs: assert svg.exists() + with open(autoband_results, encoding="utf8") as file: + bands = yaml.safe_load(file) + assert "eigenvector" in bands["phonon"][0]["band"][0].keys() def test_supercell(tmp_path):