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

Develop 2 master #37

Merged
merged 22 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
987e4e6
Fix Authors section with a list
brunato Dec 24, 2021
d388dfa
fix import of etree_tostring from xmlschema
pietrodelugas Mar 9, 2023
29461d7
fix get_atomic_constraints_card
pietrodelugas Mar 10, 2023
5016fc5
add HUBBARD card for new LDA+U format
pietrodelugas Mar 13, 2023
a654c16
fixing tests after commit 5016fc5c
pietrodelugas Mar 13, 2023
7137e3f
adding schema argument to xml2qeinput.py
pietrodelugas Mar 13, 2023
008fcfb
fixing flake8 tests
pietrodelugas Mar 13, 2023
1dc07cd
Merge pull request #36 from pietrodelugas/update_formats
pietrodelugas Mar 14, 2023
7c25567
Update Tox and CI tests
brunato Mar 14, 2023
a9e67e6
adding epw schema
pietrodelugas Apr 19, 2023
f85cce0
adding EPW document converters and first test
pietrodelugas Apr 19, 2023
fa76289
adding title on top of namelist
pietrodelugas Apr 19, 2023
63b4650
add epw to test_converters
pietrodelugas Apr 19, 2023
05b3daa
streamline management of wdata lines in EPW converter
pietrodelugas Apr 20, 2023
36e3b6e
update tests
pietrodelugas Apr 20, 2023
08eae5d
correct PEP complaints in xml2qeinput
pietrodelugas Apr 20, 2023
fab5e31
add PW schema v230310
pietrodelugas Mar 14, 2023
eed8e09
further develop
pietrodelugas Apr 19, 2023
c9466b3
refactor xml2qeinput so that is uses fetch schema
pietrodelugas Apr 20, 2023
cdfe1c6
add tests for the new Hubbard input format
pietrodelugas Apr 20, 2023
ee4ccca
fixing PEP flake and similar
pietrodelugas Apr 20, 2023
75db960
renaming INPUT_SCHEMA to schema_fn
pietrodelugas Apr 21, 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
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand All @@ -29,6 +29,7 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Lint with flake8
if: ${{ matrix.python-version != '3.7' }}
run: |
flake8 qeschema --max-line-length=100 --statistics
- name: Run tests
Expand Down
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ Loaded data can be decoded to Python data dictionary or written to JSON or YAML

Authors
-------
Davide Brunato
Pietro Delugas
Giovanni Borghi
Alexandr Fonari
* Davide Brunato
* Pietro Delugas
* Giovanni Borghi
* Alexandr Fonari


License
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
# -- Project information -----------------------------------------------------

project = 'qeschema'
copyright = '2015-2022, Quantum Espresso Foundation and SISSA'
copyright = '2015-2023, Quantum Espresso Foundation and SISSA'
author = 'Davide Brunato, Pietro Delugas'

# The full version, including alpha/beta/rc tags
release = '1.4.0'
release = '1.5.0'


# -- General configuration ---------------------------------------------------
Expand Down
18 changes: 10 additions & 8 deletions qeschema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@
# Authors: Davide Brunato
#
from .documents import XmlDocument, QeDocument, PwDocument, PhononDocument, \
NebDocument, TdDocument, TdSpectrumDocument, XSpectraDocument
from .converters import RawInputConverter, PwInputConverter, PhononInputConverter, \
NebInputConverter, TdInputConverter, TdSpectrumInputConverter, XSpectraInputConverter
NebDocument, TdDocument, TdSpectrumDocument, XSpectraDocument, EPWDocument
from .converters import RawInputConverter, PwInputConverter, \
PhononInputConverter, NebInputConverter, TdInputConverter, \
TdSpectrumInputConverter, XSpectraInputConverter, EPWInputConverter
from .exceptions import QESchemaError, XmlDocumentError
from .utils import set_logger

__version__ = '1.4.0'
__version__ = '1.5.0'

__all__ = [
'XmlDocument', 'QeDocument', 'PwDocument', 'PhononDocument', 'NebDocument',
'TdDocument', 'TdSpectrumDocument', 'RawInputConverter', 'PwInputConverter',
'PhononInputConverter', 'TdInputConverter', 'TdSpectrumInputConverter',
'NebInputConverter', 'QESchemaError', 'XmlDocumentError', 'set_logger', 'hdf5',
'XSpectraDocument', 'XSpectraInputConverter'
'TdDocument', 'TdSpectrumDocument', 'EPWDocument', 'RawInputConverter',
'PwInputConverter', 'PhononInputConverter', 'TdInputConverter',
'TdSpectrumInputConverter', 'NebInputConverter', 'QESchemaError',
'XmlDocumentError', 'set_logger', 'hdf5', 'XSpectraDocument',
'XSpectraInputConverter', 'EPWInputConverter'
]
91 changes: 78 additions & 13 deletions qeschema/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
Conversion functions for Quantum Espresso cards.
"""
import logging
from typing import Union, List

logger = logging.getLogger('qeschema')

Expand Down Expand Up @@ -130,24 +129,19 @@ def get_atomic_constraints_card(name, **kwargs):
:return: List of strings
"""
try:
num_of_constraints = kwargs['num_of_constraints']
tolerance = kwargs['tolerance']
atomic_constraints = kwargs['atomic_constraints']
num_of_constraints = kwargs['atomic_constraints']['num_of_constraints']
tolerance = kwargs['atomic_constraints']['tolerance']
atomic_constraints = kwargs['atomic_constraints']['atomic_constraint']
except KeyError:
logger.error("Missing required arguments when building CONSTRAINTS card!")
return []

lines = [name, '{0} {1}'.format(num_of_constraints, tolerance)]
lines = [name, f"{num_of_constraints} {tolerance}"]
for constraint in atomic_constraints:
constr_parms = constraint['constr_parms'] # list with 4 float items
constr_parms.extend([0] * max(0, 4 - len(constr_parms)))
constr_parms = constraint['constr_parms'] # list with at most 4 float items
constr_type = constraint['constr_type'] # string
constr_target = constraint['constr_target'] # float
lines.append('{0} {1} {2}'.format(
constr_type,
' '.join([str(item) for item in constr_parms]),
constr_target
))
constr_target = constraint.get('constr_target', "") # float or empty
lines.append(f"{constr_type} {' '.join([str(_) for _ in constr_parms])} {constr_target}")
return lines


Expand Down Expand Up @@ -195,6 +189,77 @@ def get_k_points_card(name, **kwargs):
return lines


def get_hubbard_card(name, **kwargs):
"""
writes the hubbard card for new format
"""
try:
new_format = kwargs['dftU']['@new_format']
except KeyError:
new_format = False
if not new_format:
return []
try:
dftu = kwargs['dftU']
except KeyError as err:
logger.error("Missing required argument %s when building "
"parameter %r", str(err), name)
return []

projtype = kwargs.get('U_projection_type', 'atomic')
lines = [f"{name} {projtype}"]
for tag in iter(['U', 'J0', 'alpha', 'beta']):
lines.extend(_hubbard_lines(dftu, tag))
for tag in iter(['J', 'U2', 'V']):
lines.extend(_hubbard_special_lines(dftu, tag))
return lines


def _hubbard_lines(dftu, tag):
related_data = dftu.get(f"Hubbard_{tag}", [])
lines = []
for value in iter(related_data if isinstance(related_data, list) else [related_data]):
specie = value['@specie']
label = value['@label']
if label != 'no Hubbard':
lines.append(f"{tag} {specie}-{label} {value['$']:8.3f}")
return lines


def _hubbard_special_lines(dftu, tag):
related_data = dftu.get(f"Hubbard_{tag}", [])
llabels = ['s', 'p', 'd', 'f']
lines = []
for value in iter(related_data if isinstance(related_data, list) else [related_data]):
specie = value['@specie']
label = value.get('@label', 'not found')
if label != 'no Hubbard':
if tag == 'J':
lines.append(f"J {specie}-{label} {value['$'][0]:8.3f}")
if 'd' in label:
lines.append(f"B {specie}-{label} {value['$'][1]:8.3f}")
elif 'f' in label:
lines.extend([f"E2 {specie}-{label} {value['$'][1]:8.3f}",
f"E3 {specie}-{label} {value['$'][2]:8.3f}"])
elif tag == 'U2':
background = value['@background']
if label == 'not found':
def labnl(nnum, lnum):
return f"{nnum}{llabels[lnum-1]}"

label = labnl(value['n2_number'], value['l2_number'])
if 'two' in background:
label = f"{label}-{labnl(value['n3_number'],value['l3_number'])}"
lines.append(f"U {specie}-{label} {value['$']:8.3f}")
elif tag == 'V':
speclab1 = f"{value['@specie1']}-{value['@label1']}"
speclab2 = f"{value['@specie2']}-{value['@label2']}"
index1 = value['@index1']
index2 = value['@index2']
lines.append(f"{tag} {speclab1} {speclab2} {index1} {index2} {value['$']:8.3f}")
return lines


def get_atomic_forces_card(name, **kwargs):
"""
Convert XML data to ATOMIC_FORCES card
Expand Down
143 changes: 130 additions & 13 deletions qeschema/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

FCP_NAMELIST = 'FCP'
PH_NAT_TODO_CARD = 'ph_nat_todo_card'
OPTIONAL_CARDS = {PH_NAT_TODO_CARD}
OPTIONAL_CARDS = {PH_NAT_TODO_CARD, "CONSTRAINTS", "HUBBARD", "SOLVENTS"}


def conversion_maps_builder(template_map):
Expand Down Expand Up @@ -363,27 +363,42 @@ class PwInputConverter(RawInputConverter):
'ecutvcut': ('SYSTEM[ecutvcut]', options.ha2ry, None)
},
'dftU': {
'lda_plus_u_kind': 'SYSTEM[lda_plus_u_kind]',
'@new_format': [('HUBBARD', cards.get_hubbard_card, None),
('SYSTEM[lda_plus_u_kind]', options.set_lda_plus_u_kind, None),
('SYSTEM[lda_plus_u]', options.set_lda_plus_u_flag, None),
('SYSTEM[Hubbard_U]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_J]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_J0]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_alpha]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_beta]', options.get_specie_related_values, None),
('SYSTEM[U_projection_type]', options.set_u_projection_type, None)],
'lda_plus_u_kind': ('SYSTEM[lda_plus_u_kind]', options.set_lda_plus_u_kind, None),
'Hubbard_U': {
'$': [('SYSTEM[Hubbard_U]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None),
('SYSTEM[lda_plus_u]', options.set_lda_plus_u_flag, None)]
},
'Hubbard_J0': {
'$': ('SYSTEM[Hubbard_J0]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_J0]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'Hubbard_alpha': {
'$': ('SYSTEM[Hubbard_alpha]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_alpha]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'Hubbard_beta': {
'$': ('SYSTEM[Hubbard_beta]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_beta]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'Hubbard_J': {
'$': ('SYSTEM[Hubbard_J]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_J]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'starting_ns': {
'$': ('SYSTEM[starting_ns_eigenvalue]', options.get_specie_related_values, None)
},
'U_projection_type': 'SYSTEM[U_projection_type]',
'U_projection_type': ('SYSTEM[U_projection_type]',
options.set_u_projection_type, None)
},
'vdW': {
'vdw_corr': 'SYSTEM[vdw_corr]',
Expand Down Expand Up @@ -561,7 +576,7 @@ def __init__(self, **kwargs):
input_namelists=('CONTROL', 'SYSTEM', 'ELECTRONS', 'IONS', 'CELL',
FCP_NAMELIST),
input_cards=('ATOMIC_SPECIES', 'ATOMIC_POSITIONS', 'K_POINTS',
'CELL_PARAMETERS', 'ATOMIC_FORCES')
'CELL_PARAMETERS', 'ATOMIC_FORCES', 'CONSTRAINTS', 'SOLVENTS', 'HUBBARD')
)
if 'xml_file' in kwargs:
self._input['CONTROL']['input_xml_schema_file'] = "{!r}".format(
Expand All @@ -578,7 +593,7 @@ class PhononInputConverter(RawInputConverter):
"""
PHONON_TEMPLATE_MAP = {
'xq': {
'$': ('qPointsSpecs', cards.get_qpoints_card, None),
'$': ('qPointsSpecs', cards.get_qpoints_card, None),
},
'scf_ph': {
'tr2_ph': "INPUTPH[tr2_ph]",
Expand Down Expand Up @@ -741,7 +756,7 @@ def __init__(self, **_kwargs):
*conversion_maps_builder(self.NEB_TEMPLATE_MAP),
input_namelists=('PATH', 'CONTROL', 'SYSTEM', 'ELECTRONS', 'IONS', 'CELL'),
input_cards=('CLIMBING_IMAGES', 'ATOMIC_SPECIES', 'ATOMIC_POSITIONS', 'K_POINTS',
'CELL_PARAMETERS', 'ATOMIC_FORCES')
'CELL_PARAMETERS', 'ATOMIC_FORCES', 'CONSTRAINTS')
)

def get_qe_input(self):
Expand Down Expand Up @@ -851,9 +866,7 @@ def get_qe_input(self):
Overrides superclass get_qe_input with use_defaults set to False.
:return: the input as obtained from its input builder
"""
temp = super(TdInputConverter, self).get_qe_input().split('\n')
for i, j in enumerate(temp):
print(i, " - ", j)
temp = super().get_qe_input().split('\n')
td = temp[1]
start = temp.index('&lr_input')
end = start + temp[start:].index('/')
Expand Down Expand Up @@ -985,3 +998,107 @@ def __init__(self, **_kwargs):
input_namelists=('input_xspectra', 'plot', 'pseudos', 'cut_occ'),
input_cards=("K_POINTS",)
)


class EPWInputConverter(RawInputConverter):
"""
converts the XML input file for EPW to the namelist format
expected by epw.x
"""
EPW_TEMPLATE_MAP = {
'control_variables': {
'prefix': "inputepw[prefix]",
'outdir': "inputepw[outdir]",
'iverbosity': "inputepw[iverbosity]",
'dvscf_dir': "inputepw[dvscf_dir]",
'filukk': "inputepw[filukk]",
'elph': "inputepw[elph]",
'ep_coupling': "inputepw[ep_coupling]",
'elecselfen': "inputepw[elecselfen]",
'phonselfen': "inputepw[phonselfen]",
'lindabs': "inputepw[lindabs]",
'band_plot': "inputepw[band_plot]",
'fermi_plot': "inputepw[fermi_plot]",
'cumulant': "inputepw[cumulant]",
'prtgkk': "inputepw[prtgkk]",
'epbread': "inputepw[epbread]",
'epbwrite': "inputepw[epbwrite]",
'epwread': "inputepw[epwread]",
'epwwrite': "inputepw[epwwrite]",
'ephwrite': "inputepw[ephwrite]",
'eig_read': "inputepw[eig_read]",
'delta_approx': "inputepw[delta_approx]",
'eps_acustic': "inputepw[eps_acustic]",
'etf_mem': "inputepw[etcmem]",
'nbndsub': "inputepw[nbndsub]",
'nq1': "inputepw[nq1]",
'nq2': "inputepw[nq2]",
'nq3': "inputepw[nq3]",
'nk1': "inputepw[nk1]",
'nk2': "inputepw[nk2]",
'nk3': "inputepw[nk3]",
'nqf1': "inputepw[nqf1]",
'nqf2': "inputepw[nqf2]",
'nqf3': "inputepw[nqf3]",
'nkf1': "inputepw[nkf1]",
'nkf2': "inputepw[nkf2]",
'nkf3': "inputepw[nkf3]",
'mp_mesh_k': "inputepw[mp_mesh_k]",
'filqf': "inputepw[filqf]",
'filkf': "inputepw[filkf]",
'vme': "inputepw[vme]",
'degaussw': "inputepw[degaussw]",
'degaussq': "inputepw[degaussq]",
'fsthick': "inputepw[fsthick]",
'ngaussw': "inputepw[ngaussw]",
'nsmear': "inputepw[nsmear]",
'delta_smear': "inputepw[delta_smear]",
'restart': "inputepw[restart]",
'restart_step': "inputepw[restart_step]",
'scissor': "inputepw[scissor]",
'lphase': "inputepw[lphase]",
'lpolar': "inputepw[lpolar]",
'efermi_read': "inputepw[efermi_read]",
'fermi_energy': "inputepw[fermi_energy]",
'lscreen': "inputepw[lscreen]",
'scr_typ': "inputepw[scr_typ]",
'fermi_diff': "inputepw[fermi_diff]",
'smear_rpa': "inputepw[smear_rpa]",
'lifc': "inputepw[lifc]",
'asr_typ': "inputepw[asr_typ]",
'wannierize': "inputepw[wannierize]",
'amass': {'$': ("inputepw[amass]", options.set_one_amass_line, None)}
},
'wannier90': {
'num_iter': "inputepw[num_iter]",
'dis_win_max': "inputepw[dis_win_max]",
'dis_win_min': "inputepw[dis_win_min]",
'dis_froz_min': "inputepw[dis_froz_min]",
'dis_froz_max': "inputepw[dis_frox_max]",
'proj': {'$': ("inputepw[proj]", options.set_one_proj_line, None)},
'bands_skipped': "inputepw[bands_skipped]",
'iprint': "inputepw[iprint]",
'wannier_plot': ["inputepw[wannier_plot]",
("inputepw[wdata]", options.set_wdata_lines, None)
],
'wannier_plot_supercell': "inputepw[wannier_plot_supercell]",
'wannier_plot_scale': "inputepw[wannier_plot_scale]",
'wannier_plot_radius': "inputepw[wannier_plot_radius]",
'wannier_plot_list': {'@segment': ("inputepw[wdata]",
options.set_wdata_lines, None)},
'wannier_plot_format': ('inputepw[wdata]',
options.set_wdata_lines, None),
'use_ws': ("inputepw[wdata]", options.set_wdata_lines, None),
'reduce_unk': "inputepw[reduce_unk]",
'scdm_proj': "inputepw[scdm_proj]",
'scdm_sigma': "inputepw[scdm_sigma]",
'auto_projections': "inputepw[auto_projections]",
'scdm_entanglement': "inputepw[scdm_entaglement]",
'scdm_mu': "inputepw[scdm_mu]",
}
}

def __init__(self, **kwargs):
super().__init__(*conversion_maps_builder(self.EPW_TEMPLATE_MAP),
input_namelists=['inputepw'],
input_cards=[])
Loading