Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Testing/Data/UnitTest/Ge-force_constants.hdf5.md5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ce75e1d1d4e693a320349b2e996f6d4a
1 change: 1 addition & 0 deletions Testing/Data/UnitTest/Ge-phonopy.yml.md5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5e3f4a778792461cfa47d5b5d1003309
2 changes: 1 addition & 1 deletion Testing/SystemTests/tests/framework/AbinsTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class AbinsCRYSTALTestT(AbinsTestingMixin, systemtesting.MantidSystemTest):
parameters are identical across calculations. In the third run the required
data /should/ be read from the hdf file.

We only check that here that the results are correct, we cannot tell if the
We only check here that the results are correct, we cannot tell if the
cache was used.
"""

Expand Down
2 changes: 1 addition & 1 deletion conda/recipes/conda_build_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ libopenblas:
# which does not require future https://github.com/conda-forge/seekpath-feedstock/pull/15/
# please remove this comment and the pins in those recipes when euphonic and seekpath release new versions
euphonic:
- '>=1.4.3,<2.0'
- '>=1.4.5,<2.0'

librdkafka:
- '>=1.6.0'
Expand Down
2 changes: 1 addition & 1 deletion docs/source/algorithms/Abins-v1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ scattering spectra (INS).

Abins requires data from existing lattice dynamics calculations to determine the phonon mode frequencies and displacements. These are used to compute INS intensities; higher-order phonons may be approximated as combinations of fundamental modes.
Several file formats are supported for frequency and displacement data at given :math:`\mathbf{q}`-points. Alternatively, force-constants data can be provided and a fine :math:`\mathbf{q}`-point mesh will be sampled automatically.
Supported codes include CASTEP (.phonon), CRYSTAL (.out), DMOL3 (.outmol), GAUSSIAN (.log), PHONOPY (.yaml), VASP (.xml) as well as some pre-processed JSON (.json) formats. For more information about the files, features and quirks of these codes see :ref:`AbinsDataFormats`.
Supported codes include CASTEP (.phonon), CRYSTAL (.out), DMOL3 (.outmol), GAUSSIAN (.log), PHONOPY (.yaml, .yml), VASP (.xml) as well as some pre-processed JSON (.json) formats. For more information about the files, features and quirks of these codes see :ref:`AbinsDataFormats`.

The user may also provide an experimental file with measured dynamical structure factor S in order to directly
compare theoretical and experimental spectra.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/algorithms/Abins2D-v1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Abins requires data from existing lattice dynamics calculations to determine the

Several file formats are supported for frequency and displacement data at given :math:`\mathbf{q}`-points. Alternatively, force-constants data can be provided and a fine :math:`\mathbf{q}`-point mesh will be sampled automatically.

Supported codes include CASTEP (.phonon), CRYSTAL (.out), DMOL3 (.outmol), GAUSSIAN (.log), PHONOPY (.yaml), VASP (.xml) as well as some pre-processed JSON (.json) formats. For more information about the files, features and quirks of theskee codes see :ref:`AbinsDataFormats`.
Supported codes include CASTEP (.phonon), CRYSTAL (.out), DMOL3 (.outmol), GAUSSIAN (.log), PHONOPY (.yaml, .yml), VASP (.xml) as well as some pre-processed JSON (.json) formats. For more information about the files, features and quirks of theskee codes see :ref:`AbinsDataFormats`.

For VASP XML inputs, it is also permitted to use a "selective dynamics" in which some atoms are frozen.
In this case, data is only available for the moving atoms and contributions from the other atoms are omitted from the calculated spectrum.
Expand Down
3 changes: 3 additions & 0 deletions docs/source/concepts/AbinsDataFormats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ It is also permitted to use a phonopy YAML file which does not contain the force
We recommend using the *force_constants.hdf5* file where practical as the read/write performance is significantly better.
(With the power and flexibility of *.yaml* comes a lot of computational overhead to read simple arrays!)

Machine-learned interatomic potential calculations with `janus-core <https://stfc.github.io/janus-core/>`_ can use Phonopy to produce phonon outputs with filenames *PREFIX-phonopy.yml* and *PREFIX-force_constants.hdf5*.
This filename convention can be used with Abins: again, the force constants file should be in the same directory as the YAML file.

VASP
----
Abins can read the frequencies and displacements from Gamma-point vibration calculations performed with the ``IBRION=5,6,7,8`` tags.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Euphonic dependency is updated to 1.4.5. Notably, this includes a
bugfix when importing force constants with dipole-dipole corrections
from Phonopy: if the supercell matrix was non-symmetric, the long-range
subtraction was done incorrectly. Calculations with "diagonal"
supercells (e.g. 2×3×4) are unaffected, and primitive-FCC or
primitive-BCC transformations should also use a symmetric matrix.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- *<prefix>-phonopy.yml* and *<prefix>-force_constants.hdf5* files
from `janus-core <https://stfc.github.io/janus-core>`_ are now
supported as input to Abins/Abins2D Algorithms. Use the
FORCE_CONSTANTS "AbInitioProgram" as for regular *phonopy.yaml*
files.
58 changes: 38 additions & 20 deletions scripts/abins/abinsalgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,27 +840,45 @@ def _validate_euphonic_input_file(cls, filename_full_path: str) -> dict:

if (suffix := path.suffix) == ".castep_bin":
# Assume any .castep_bin file is valid choice
pass

elif suffix == ".yaml":
# Check .yaml files have expected keys for Phonopy force constants
with open(filename_full_path, "r") as yaml_file:
phonon_data = yaml.load(yaml_file, Loader=SafeLoader)

if {"phonopy", "force_constants"}.issubset(phonon_data):
pass

elif "phonopy" in phonon_data:
# Phonon file without force constants included: they could be in
# a FORCE_CONSTANTS or force_constants.hdf5 file so check if one exists
fc_filenames = ("FORCE_CONSTANTS", "force_constants.hdf5")
if not any(map(lambda fc_filename: (path.parent / fc_filename).is_file(), fc_filenames)):
return dict(
Invalid=True,
Comment=f"Could not find force constants in {filename_full_path}, or find data file {' or '.join(fc_filenames)}",
)
return dict(Invalid=False, Comment="")

if suffix not in (".yaml", ".yml"):
return dict(Invalid=True, Comment="Invalid extension: FORCECONSTANTS requires .castep_bin, .yaml or .yml")

# Check .yaml files have expected keys for Phonopy force constants
with open(filename_full_path, "r") as yaml_file:
phonon_data = yaml.load(yaml_file, Loader=SafeLoader)

if {"phonopy", "force_constants"}.issubset(phonon_data):
# Force constants are in the yaml file: good
return dict(Invalid=False, Comment="")

if "phonopy" not in phonon_data:
# Not a Phonopy file: can't use this
return dict(Invalid=True, Comment=f"No 'phonopy' section found in {filename_full_path}")

# Phonopy file without force constants: they must be in another file

# Check if following janus conventions:
# /parent/seedname-phonopy.yml -> /parent/seedname-force_constants.hdf5
janus_phonopy_re = "(?P<seedname>.+)-phonopy.yml"
fc_filenames = ("FORCE_CONSTANTS", "force_constants.hdf5")
if re_match := re.match(janus_phonopy_re, path.name):
fc_file = path.parent / f"{re_match['seedname']}-force_constants.hdf5"
if not fc_file.is_file():
return dict(
Invalid=True,
Comment=f"Could not find force constants in {filename_full_path}, or find data file {fc_file}",
)

# Otherwise FC could be in a FORCE_CONSTANTS or force_constants.hdf5 file
elif not any(map(lambda fc_filename: (path.parent / fc_filename).is_file(), fc_filenames)):
return dict(
Invalid=True,
Comment=f"Could not find force constants in {filename_full_path}, or find data file {' or '.join(fc_filenames)}",
)

# Did not return already: No problems found
# Phonopy YAML with available force constants
return dict(Invalid=False, Comment="")

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion scripts/abins/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
MAX_ORDER = 4 # max quantum order event

ALL_SUPPORTED_AB_INITIO_PROGRAMS = ["CRYSTAL", "CASTEP", "DMOL3", "GAUSSIAN", "VASP"]
AB_INITIO_FILE_EXTENSIONS = ["castep_bin", "hdf5", "json", "out", "outmol", "phonon", "log", "LOG", "mol", "yaml", "xml"]
AB_INITIO_FILE_EXTENSIONS = ["castep_bin", "hdf5", "json", "out", "outmol", "phonon", "log", "LOG", "mol", "yaml", "yml", "xml"]


ONE_DIMENSIONAL_INSTRUMENTS = ["TOSCA", "Lagrange"]
Expand Down
24 changes: 24 additions & 0 deletions scripts/test/Abins/AbinsAlgorithmTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ def test_bad_atom_info(self):
species.neutron_data


class AbinsAlgorithmValidatorsTest(unittest.TestCase):
"""Test input validators"""

def test_validate_euphonic_yml(self):
"""Check that force constants are located for .yml input"""
# with open(abins.test_helpers.find_file(seedname + "_data.txt")) as data_file:
# def _validate_euphonic_input_file(cls, filename_full_path: str) -> dict:
from abins.test_helpers import find_file

issues = AbinsAlgorithm._validate_euphonic_input_file(find_file("Al_LoadPhonopy.yaml"))
self.assertEqual(issues, {"Invalid": False, "Comment": ""})

issues = AbinsAlgorithm._validate_euphonic_input_file(find_file("Ge-phonopy.yml"))
self.assertEqual(issues, {"Invalid": False, "Comment": ""})

issues = AbinsAlgorithm._validate_euphonic_input_file(find_file("Si2-phonon_LoadCASTEP.phonon"))
self.assertEqual(issues, {"Invalid": True, "Comment": "Invalid extension: FORCECONSTANTS requires .castep_bin, .yaml or .yml"})

# Non-phonopy yaml from another test
wrong_yaml = find_file("ISISPowderRunDetailsTestCallable.yaml")
issues = AbinsAlgorithm._validate_euphonic_input_file(wrong_yaml)
self.assertEqual(issues, {"Invalid": True, "Comment": f"No 'phonopy' section found in {wrong_yaml}"})


class AbinsAlgorithmMethodsTest(unittest.TestCase):
"""Test static methods on AbinsAlgorithm"""

Expand Down