Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hubbard data structure for handling newest QuantumESPRESSO versions (>=7.1) #849

Merged
merged 45 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
0093376
New data type for Hubbard parameters
bastonero Jul 29, 2022
ca943e9
Merge branch 'main' of https://github.com/aiidateam/aiida-quantumespr…
bastonero Sep 26, 2022
e360dee
New methods added: checks, parser for QE 7.1, shuffle option for `sta…
bastonero Sep 30, 2022
4b1d7a1
Implemented more methods to meet QE standards
bastonero Oct 7, 2022
c04c5f0
Some bug fixes
bastonero Oct 12, 2022
4020480
New data type for Hubbard parameters
bastonero Jul 29, 2022
3db23cc
New methods added: checks, parser for QE 7.1, shuffle option for `sta…
bastonero Sep 30, 2022
41097c0
Implemented more methods to meet QE standards
bastonero Oct 7, 2022
d1e2808
Some bug fixes
bastonero Oct 12, 2022
ed2b1d4
Add entry point for `HubbardStructureData`
mbercx Oct 19, 2022
3ea1ece
Merge branch 'feature/data/hubbard' of https://github.com/aiidateam/a…
bastonero Oct 20, 2022
653be49
Add entry point for `HubbardStructureData`
mbercx Oct 20, 2022
ae1dbe8
Write HUBBARD card for `HubbardStructureData`
mbercx Oct 20, 2022
1eb05dd
Merge branch 'feature/data/hubbard' of https://github.com/aiidateam/a…
bastonero Oct 20, 2022
f8ff64b
New data type for Hubbard parameters
bastonero Jul 29, 2022
2c6aca4
New methods added: checks, parser for QE 7.1, shuffle option for `sta…
bastonero Sep 30, 2022
8efb22e
Implemented more methods to meet QE standards
bastonero Oct 7, 2022
3ea3381
Some bug fixes
bastonero Oct 12, 2022
da950d4
Add entry point for `HubbardStructureData`
mbercx Oct 20, 2022
db08646
Write HUBBARD card for `HubbardStructureData`
mbercx Oct 20, 2022
27eccd1
Merge branch 'feature/data/hubbard' of https://github.com/aiidateam/a…
bastonero Nov 21, 2022
c09a12e
Merge branch 'main' of https://github.com/aiidateam/aiida-quantumespr…
bastonero Nov 28, 2022
3e2c388
Fix the pre-commit
sphuber Jan 24, 2023
a2dd696
Move `hubbard_parameters` in repository
bastonero Feb 13, 2023
fb440b1
Small fixes
bastonero Feb 13, 2023
88d9502
Add latest develop XSD schema for `pw.x`
mbercx Feb 15, 2023
c91e7f7
Write translation as `list` to make params JSON serialisable
mbercx Feb 15, 2023
50418c8
Feature: Hubbard data schema using `pydantic`
bastonero Mar 21, 2023
803f477
Refining and optimizing `HubbardStructureData`
bastonero Mar 21, 2023
8202c4e
Add `utils/hubbard`, fixes and renaming
bastonero Mar 22, 2023
d815ab9
Add `reorder_atoms` + clean-up with better logics
bastonero Mar 23, 2023
9691b31
Small fixes
bastonero Mar 23, 2023
a176370
Add useful method to `utils/hubbard`
bastonero Mar 24, 2023
85e72d3
Adapt `BasePwCpInputGenerator`
bastonero Mar 24, 2023
499bfef
Small bug fix + test where failed
bastonero Mar 24, 2023
5ff0c92
Merge branch 'main' into feature/data/hubbard
sphuber Mar 24, 2023
211f165
Remove xml schema
bastonero Mar 24, 2023
8a5540a
Fix the `pre-commit`
bastonero Mar 24, 2023
9bc0b75
Improving docstrings and adding comments
bastonero Mar 25, 2023
0e734c1
Address review requests
bastonero Mar 28, 2023
cf498e9
Add regex to tests
bastonero Mar 28, 2023
264136b
Change default `hubbard_type` to `V` for intersite
bastonero Apr 5, 2023
62b7029
Add new method to `utils.hubbard`
bastonero Apr 5, 2023
0c4ad97
Fix typos and typing
bastonero Apr 5, 2023
ef5cfd2
Merge branch 'main' into feature/data/hubbard
sphuber Apr 6, 2023
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
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies = [
'importlib_resources',
'jsonschema',
'numpy',
'pydantic',
'packaging',
'qe-tools~=2.0',
'xmlschema~=1.2,>=1.2.5'
Expand Down Expand Up @@ -86,6 +87,7 @@ aiida-quantumespresso = 'aiida_quantumespresso.cli:cmd_root'

[project.entry-points.'aiida.data']
'quantumespresso.force_constants' = 'aiida_quantumespresso.data.force_constants:ForceConstantsData'
'quantumespresso.hubbard_structure' = 'aiida_quantumespresso.data.hubbard_structure:HubbardStructureData'

[project.entry-points.'aiida.parsers']
'quantumespresso.cp' = 'aiida_quantumespresso.parsers.cp:CpParser'
Expand Down Expand Up @@ -150,7 +152,7 @@ ignore = [
]

[tool.pylint.master]
load-plugins = ['pylint_aiida']
load-plugins = ['pylint_aiida','pylint.extensions.no_self_use']

[tool.pylint.format]
max-line-length = 120
Expand Down
8 changes: 8 additions & 0 deletions src/aiida_quantumespresso/calculations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
from aiida.plugins import DataFactory
from qe_tools.converters import get_parameters_from_cell

from aiida_quantumespresso.data.hubbard_structure import HubbardStructureData
from aiida_quantumespresso.utils.convert import convert_input_to_namelist_entry
from aiida_quantumespresso.utils.hubbard import HubbardUtils

from .base import CalcJob
from .helpers import QEInputValidationError
Expand Down Expand Up @@ -685,6 +687,10 @@ def _generate_PWCPinputdata(cls, parameters, settings, pseudos, structure, kpoin
kpoints_card = ''.join(kpoints_card_list)
del kpoints_card_list

# HUBBARD CARD
hubbard_card = HubbardUtils(structure).get_hubbard_card() if isinstance(structure, HubbardStructureData) \
else None

# =================== NAMELISTS AND CARDS ========================
try:
namelists_toprint = settings.pop('NAMELISTS')
Expand Down Expand Up @@ -728,6 +734,8 @@ def _generate_PWCPinputdata(cls, parameters, settings, pseudos, structure, kpoin
if cls._use_kpoints:
inputfile += kpoints_card
inputfile += cell_parameters_card
if hubbard_card is not None:
inputfile += hubbard_card

# Generate additional cards bases on input parameters and settings that are subclass specific
tail = cls._generate_PWCP_input_tail(input_params=input_params, settings=settings)
Expand Down
2 changes: 2 additions & 0 deletions src/aiida_quantumespresso/common/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
"""Common modules to be shared with other aiida plugins."""
161 changes: 161 additions & 0 deletions src/aiida_quantumespresso/common/hubbard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# -*- coding: utf-8 -*-
"""Utility class and functions for HubbardStructureData."""
# pylint: disable=no-name-in-module, invalid-name
from typing import List, Literal, Tuple

from pydantic import BaseModel, conint, constr, validator

__all__ = ('HubbardParameters', 'Hubbard')


class HubbardParameters(BaseModel):
"""Class for describing onsite and intersite Hubbard interaction parameters.

.. note: allowed manifold formats are:
* {N}{L} (2 characters)
* {N1}{L1}-{N2}{L2} (5 characters)

N = quantum number (1,2,3,...); L = orbital letter (s,p,d,f,g,h)
"""

atom_index: conint(strict=True, ge=0)
"""Atom index in the abstract structure."""

atom_manifold: constr(strip_whitespace=True, to_lower=True, min_length=2, max_length=5)
"""Atom manifold (syntax is `3d`, `3d-2p`)."""

neighbour_index: conint(strict=True, ge=0)
"""Neighbour index in the abstract structure."""

neighbour_manifold: constr(strip_whitespace=True, to_lower=True, min_length=2, max_length=5)
"""Atom manifold (syntax is `3d`, `3d-2p`)."""

translation: Tuple[conint(strict=True), conint(strict=True), conint(strict=True)]
"""Translation vector referring to the neighbour atom, (3,) shape list of ints."""

value: float
"""Value of the Hubbard parameter, expessed in eV."""

hubbard_type: Literal['Ueff', 'U', 'V', 'J', 'B', 'E2', 'E3']
"""Type of the Hubbard parameters used (`Ueff`, `U`, `V`, `J`, `B`, `E2`, `E3`)."""

@validator('atom_manifold', 'neighbour_manifold') # cls is mandatory to use
def check_manifolds(cls, value): # pylint: disable=no-self-argument, no-self-use
"""Check the validity of the manifold input.

Allowed formats are:
* {N}{L} (2 characters)
* {N1}{L1}-{N2}{L2} (5 characters)

N = quantum number (1,2,3,...); L = orbital letter (s,p,d,f,g,h)
"""
length = len(value)
if length not in [2, 5]:
raise ValueError(f'invalid length ``{length}``. Only 2 or 5.')
if length == 2:
if not value[0] in [str(_ + 1) for _ in range(6)]:
raise ValueError(f'invalid quantum number {value[0]}')
if not value[1] in ['s', 'p', 'd', 'f', 'h']:
raise ValueError(f'invalid manifold symbol {value[1]}')
if length == 5:
if not value[2] == '-':
raise ValueError(f'the separator {value[0]} is not allowed. Only `-`')
if not value[3] in [str(_ + 1) for _ in range(6)]:
raise ValueError(f'the quantum number {value[0]} is not correct')
if not value[4] in ['s', 'p', 'd', 'f', 'h']:
raise ValueError(f'the manifold number {value[1]} is not correct')
return value

def to_tuple(self) -> Tuple[int, str, int, str, float, Tuple[int, int, int], str]:
bastonero marked this conversation as resolved.
Show resolved Hide resolved
"""Return the parameters as a tuple.

The parameters have the following order:
* atom_index
* atom_manifold
* neighbour_index
* neighbour_manifold
* value
* translationr
* hubbard_type
"""
return (
self.atom_index, self.atom_manifold, self.neighbour_index, self.neighbour_manifold, self.value,
self.translation, self.hubbard_type
)

@staticmethod
def from_tuple(hubbard_parameters: Tuple[int, str, int, str, float, Tuple[int, int, int], str]):
"""Return a :meth:`~aiida_quantumespresso.common.hubbard.HubbardParameters` instance from a list.

The parameters within the list must have the following order:
* atom_index
* atom_manifold
* neighbour_index
* neighbour_manifold
* value
* translation
* hubbard_type
"""
keys = [
'atom_index',
'atom_manifold',
'neighbour_index',
'neighbour_manifold',
'value',
'translation',
'hubbard_type',
]
return HubbardParameters(**dict(zip(keys, hubbard_parameters)))


class Hubbard(BaseModel):
"""Class for complete description of Hubbard interactions."""

parameters: List[HubbardParameters]
"""List of :meth:`~aiida_quantumespress.common.hubbard.HubbardParameters`."""

projectors: Literal['atomic',
'ortho-atomic',
'norm-atomic',
'wannier-functions',
'pseudo-potentials',
] = 'ortho-atomic'
"""Name of the projectors used. Allowed values are:
'atomic', 'ortho-atomic', 'norm-atomic', 'wannier-functions', 'pseudo-potentials'."""

formulation: Literal['dudarev', 'liechtenstein'] = 'dudarev'
"""Hubbard formulation used. Allowed values are: 'dudarev', `liechtenstein`."""

def to_list(self) -> List[Tuple[int, str, int, str, float, Tuple[int, int, int], str]]:
"""Return the Hubbard `parameters` as a list of lists.

The parameters have the following order within each list:
* atom_index
* atom_manifold
* neighbour_index
* neighbour_manifold
* value
* translation
* hubbard_type
"""
return [params.to_tuple() for params in self.parameters]

@staticmethod
def from_list(
parameters: List[Tuple[int, str, int, str, float, Tuple[int, int, int], str]],
projectors: str = 'ortho-atomic',
formulation: str = 'dudarev',
):
"""Return a :meth:`~aiida_quantumespresso.common.hubbard.Hubbard` instance from a list of tuples.

Each list must contain the hubbard parameters in the following order:
* atom_index
* atom_manifold
* neighbour_index
* neighbour_manifold
* value
* translation
* hubbard_type
"""
parameters = [HubbardParameters.from_tuple(value) for value in parameters]
return Hubbard(parameters=parameters, projectors=projectors, formulation=formulation)
Loading