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

Add feature: XspectraCoreWorkChain #872

Merged
merged 59 commits into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
11e9c65
Upload of new CalcJob files
PNOGillespie May 9, 2022
0c6373a
Upload of Parser classes for new CalcJobs
PNOGillespie May 9, 2022
5d14f11
Added XSpectra entry points
PNOGillespie May 9, 2022
4c36b55
Cleaned up docstrings and added newline after return statement
PNOGillespie May 19, 2022
0e62357
Cleaned up xspectra.py and added newline after return statement
PNOGillespie May 19, 2022
8b73bd9
Remove upf2plotcore CalcJob class
PNOGillespie May 30, 2022
bd4274a
Remove upf2plotcore Parser class
PNOGillespie May 30, 2022
ee2e9ef
Remove entry points for upf2plotcore
PNOGillespie May 30, 2022
6c39561
Update src/aiida_quantumespresso/calculations/xspectra.py
PNOGillespie Jun 6, 2022
0c20f58
Correct Capitalization
PNOGillespie Jun 6, 2022
fdbddaa
Correct Capitalization
PNOGillespie Jun 6, 2022
5f7844e
Correct Capitalization
PNOGillespie Jun 6, 2022
811066b
Correct Capitalization
PNOGillespie Jun 6, 2022
a41de8c
Merge branch 'aiidateam:develop' into develop
PNOGillespie Jun 8, 2022
a7390e3
`XspectraCalculation`: revised method for adding kpoints and core wav…
PNOGillespie Jun 9, 2022
3c83c4d
`XspectraParser`: Added parsing for spin-polarised calculations, remo…
PNOGillespie Jun 9, 2022
f12cf09
`XspectraCalculation`: Fixed wording of error codes
PNOGillespie Jun 14, 2022
d5530c6
`XspectraCalculation`: Updated `_Plotcore_FILENAME`
PNOGillespie Jun 20, 2022
75ba5d8
`XspectraParser`: Fixed various errors in `parse`
PNOGillespie Jun 20, 2022
5f4bd99
Added various tests for `XspectraParser`
PNOGillespie Jun 20, 2022
c6f4485
Merge branch 'aiidateam:develop' into develop
PNOGillespie Jul 13, 2022
875fa58
`XspectraCalculation`+`XspectraParser`: Added Various Extra Features
PNOGillespie Sep 2, 2022
793b391
Tests: Update `XspectraParser` Tests for Latest Commit
PNOGillespie Sep 2, 2022
ec841e4
Merge branch 'aiidateam:main' into develop
PNOGillespie Sep 2, 2022
8427a55
Merge branch 'develop' of https://github.com/PNOGillespie/aiida-quant…
PNOGillespie Sep 2, 2022
f0b00a5
`XspectraCalculation`: Fix unnecessary bracketing
PNOGillespie Sep 12, 2022
63b32f6
`XspectraCalculation`: Minor change to `gamma_file` input check
PNOGillespie Sep 12, 2022
746770e
`XspectraCalculation`: Change of walltime error code
PNOGillespie Sep 12, 2022
6eb8ace
`XspectraParser`: Change of walltime error code
PNOGillespie Sep 12, 2022
6742ff3
Tests: Update of error code text
PNOGillespie Sep 12, 2022
8b84c55
`XspectraCalculation`: Cleanup code for `restart_flag`
PNOGillespie Sep 12, 2022
ab9ba9f
Tests: Trim contents of `aiida.out` for `failed_walltime`
PNOGillespie Sep 12, 2022
a6ac39a
Merge branch 'develop' of https://github.com/PNOGillespie/aiida-quant…
PNOGillespie Sep 12, 2022
e0529ec
Merge branch 'aiidateam:main' into develop
PNOGillespie Sep 12, 2022
5a0e90f
Merge branch 'main' into develop
PNOGillespie Sep 26, 2022
767e2d6
Update tests/parsers/test_xspectra.py
PNOGillespie Sep 27, 2022
ae91712
Merge branch 'aiidateam:main' into develop
PNOGillespie Sep 27, 2022
a2c1321
Merge branch 'aiidateam:main' into develop
PNOGillespie Oct 14, 2022
dd73851
Merge branch 'aiidateam:main' into develop
PNOGillespie Oct 21, 2022
2a73bd5
Merge branch 'aiidateam:main' into develop
PNOGillespie Oct 27, 2022
b2c4b83
`XspectraParser`: Fix bugs in parsing vector/coord system
PNOGillespie Sep 21, 2022
d6577fa
Hotfix: Update Previous Commit to `XspectraParser`
PNOGillespie Sep 21, 2022
af1822d
`XspectraParser`: Improve reliability of parsing method
PNOGillespie Sep 30, 2022
42d66bb
`XspectraParser`: Updates to parser dict keys and tests
PNOGillespie Oct 17, 2022
df1def4
`XspectraParser`: Change `output_parameter` keys and add defaults
PNOGillespie Oct 28, 2022
9bb7cbf
Merge branch 'aiidateam:main' into develop
PNOGillespie Oct 28, 2022
4a058f5
Merge branch 'develop' of https://github.com/PNOGillespie/aiida-quant…
PNOGillespie Oct 28, 2022
ee58a8f
Merge branch 'aiidateam:main' into develop
PNOGillespie Nov 11, 2022
ab5559a
Merge branch 'aiidateam:main' into develop
PNOGillespie Nov 22, 2022
5c68963
Merge branch 'aiidateam:main' into develop
PNOGillespie Dec 14, 2022
ede83a3
Merge branch 'aiidateam:main' into develop
PNOGillespie Dec 16, 2022
bdf609e
Add Feature: `XspectraCoreWorkChain`
PNOGillespie Dec 16, 2022
4e750ae
Merge branch 'develop' into feature/xspectra-core-workchain
PNOGillespie Dec 16, 2022
2a8a158
Tests: Fix oversight in `serialize_builder` reference file
PNOGillespie Dec 16, 2022
b77eaf3
Merge branch 'main' into feature/xspectra-core-workchain
PNOGillespie Jan 20, 2023
a66a96d
`XspectraCoreWorkChain`: Requested Changes (1)
PNOGillespie Jan 27, 2023
52424f2
Apply suggestions from code review
sphuber Jan 30, 2023
f17b601
Update the docs
sphuber Jan 30, 2023
33bb8a8
Merge branch 'main' into feature/xspectra-core-workchain
sphuber Jan 30, 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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ aiida-quantumespresso = 'aiida_quantumespresso.cli:cmd_root'
'quantumespresso.matdyn.base' = 'aiida_quantumespresso.workflows.matdyn.base:MatdynBaseWorkChain'
'quantumespresso.pdos' = 'aiida_quantumespresso.workflows.pdos:PdosWorkChain'
'quantumespresso.xspectra.base' = 'aiida_quantumespresso.workflows.xspectra.base:XspectraBaseWorkChain'
'quantumespresso.xspectra.core' = 'aiida_quantumespresso.workflows.xspectra.core:XspectraCoreWorkChain'

[tool.flit.module]
name = 'aiida_quantumespresso'
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
"""CalcFunction to compute the powder spectrum of a set of XANES spectra from ``XspectraCalculation``."""
from aiida.common import ValidationError
from aiida.engine import calcfunction
from aiida.orm import XyData


@calcfunction
def get_powder_spectrum(**kwargs): # pylint: disable=too-many-statements
"""Combine the given spectra into a single "Powder" spectrum, representing the XAS of a powder sample.

The function expects between 1 and 3 XyData nodes from ``XspectraCalculation`` whose
polarisation vectors are the basis vectors of the original crystal structure (100, 010, 001).
"""
spectra = [node for node in kwargs.values() if isinstance(node, XyData)]
vectors = [node.creator.res['xepsilon'] for node in spectra]

if len(vectors) > 3:
raise ValidationError(f'Expected between 1 and 3 XyData nodes as input, but {len(spectra)} were given.')

# If the system is isochoric (e.g. a cubic system) then the three basis vectors are
# equal to each other, thus we simply return the
if len(vectors) == 1:
vector = vectors[0]
vector_string = f'{float(vector[0])} {float(vector[1])} {float(vector[2])}'
if vector not in [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]:
raise ValidationError(
f'Polarisation vector ({vector_string}) does not correspond to a crystal basis vector (100, 010, 001)'
)

powder_spectrum = spectra[0]
powder_x = powder_spectrum.get_x()[1]
powder_y = powder_spectrum.get_y()[0][1]

powder_data = XyData()
powder_data.set_x(powder_x, 'energy', 'eV')
powder_data.set_y(powder_y, 'sigma', 'n/a')

# if the system is dichoric (e.g. a hexagonal system) then the A and B periodic
# dimensions are equal to each other by symmetry, thus the powder spectrum is simply
# the average of 2x the 1 0 0 eps vector and 1x the 0 0 1 eps vector
if len(vectors) == 2:
# Since the individual vectors are labelled, we can extract just the spectra needed
# to produce the powder and leave the rest

spectrum_a = None
spectrum_c = None
for vector, spectrum in zip(vectors, spectra):
vector_string = f'{float(vector[0])} {float(vector[1])} {float(vector[2])}'
if vector in [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]:
spectrum_a = spectrum
elif vector == [0.0, 0.0, 1.0]:
spectrum_c = spectrum
else:
raise ValidationError(
f'Polarisation vector ({vector_string}) does not correspond to a crystal basis vector'
' (100, 010, 001)'
)

if spectrum_a and not spectrum_c:
raise ValidationError(f'Found no polarisation vector for the C-axis ([0, 0, 1]), found instead: {vectors}.')
powder_x = spectrum_a.get_x()[1]
yvals_a = spectrum_a.get_y()[0][1]
yvals_c = spectrum_c.get_y()[0][1]

powder_y = ((yvals_a * 2) + yvals_c) / 3
powder_data = XyData()
powder_data.set_x(powder_x, 'energy', 'eV')
powder_data.set_y(powder_y, 'sigma', 'n/a')

# if the system is trichoric (e.g. a monoclinic system) then no periodic dimensions
# are equal by symmetry, thus the powder spectrum is the average of the three basis
# dipole vectors (1.0 0.0 0.0, 0.0 1.0 0.0, 0.0 0.0 1.0)
if len(vectors) == 3:
# Since the individual vectors are labelled, we can extract just the spectra needed to
# produce the powder and leave the rest
for vector, spectra in zip(vectors, spectra):
vector_string = f'{float(vector[0])} {float(vector[1])} {float(vector[2])}'
if vector == [1.0, 0.0, 0.0]:
spectrum_a = spectra
elif vector == [0.0, 1.0, 0.0]:
spectrum_b = spectra
elif vector == [0.0, 0.0, 1.0]:
spectrum_c = spectra
else:
raise ValidationError(
f'Polarisation vector ({vector_string}) does not correspond to a crystal basis vector'
' (100, 010, 001)'
)

powder_x = spectrum_a.get_x()[1]
yvals_a = spectrum_a.get_y()[0][1]
yvals_b = spectrum_b.get_y()[0][1]
yvals_c = spectrum_c.get_y()[0][1]

powder_y = (yvals_a + yvals_b + yvals_c) / 3

powder_data = XyData()
powder_data.set_x(powder_x, 'energy', 'eV')
powder_data.set_y(powder_y, 'sigma', 'n/a')

return powder_data
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
"""CalcFunction to merge multiple ``XyData`` nodes of calculated XANES spectra into a new ``XyData`` node."""
from aiida.engine import calcfunction
from aiida.orm import XyData


@calcfunction
def merge_spectra(**kwargs):
"""Compile all calculated spectra into a single ``XyData`` node for easier plotting.

The keyword arguments must be an arbitrary number of ``XyData`` nodes from
the `output_spectra` of `XspectraCalculation`s, all other `kwargs` will be discarded at
runtime.

Returns a single ``XyData`` node where each set of y values is labelled
according to the polarisation vector used for the `XspectraCalculation`.
"""
output_spectra = XyData()
y_arrays_list = []
y_units_list = []
y_labels_list = []

spectra = [node for label, node in kwargs.items() if isinstance(node, XyData)]

for spectrum_node in spectra:
calc_node = spectrum_node.creator
calc_out_params = calc_node.res
eps_vector = calc_out_params['xepsilon']

old_y_component = spectrum_node.get_y()
if len(old_y_component) == 1:
y_array = old_y_component[0][1]
y_units = old_y_component[0][2]
y_arrays_list.append(y_array)
y_units_list.append(y_units)
y_labels_list.append(f'sigma_{eps_vector[0]}_{eps_vector[1]}_{eps_vector[2]}')
elif len(old_y_component) == 3:
y_tot = old_y_component[0][1]
y_tot_units = old_y_component[0][2]
y_tot_label = f'sigma_tot_{eps_vector[0]}_{eps_vector[1]}_{eps_vector[2]}'
y_arrays_list.append(y_tot)
y_units_list.append(y_tot_units)
y_labels_list.append(y_tot_label)

y_up = old_y_component[1][1]
y_up_units = old_y_component[1][2]
y_up_label = f'sigma_up_{eps_vector[0]}_{eps_vector[1]}_{eps_vector[2]}'
y_arrays_list.append(y_up)
y_units_list.append(y_up_units)
y_labels_list.append(y_up_label)

y_down = old_y_component[2][1]
y_down_units = old_y_component[2][2]
y_down_label = f'sigma_down_{eps_vector[0]}_{eps_vector[1]}_{eps_vector[2]}'
y_arrays_list.append(y_down)
y_units_list.append(y_down_units)
y_labels_list.append(y_down_label)

x_array = spectrum_node.get_x()[1]
x_label = spectrum_node.get_x()[0]
x_units = spectrum_node.get_x()[2]

output_spectra.set_x(x_array, x_label, x_units)
output_spectra.set_y(y_arrays_list, y_labels_list, y_units_list)

return output_spectra
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
default_inputs:
sphuber marked this conversation as resolved.
Show resolved Hide resolved
SYSTEM:
tot_charge: 1
default_treatment: full
treatments:
full:
description: 'Core-hole treatment using a formal countercharge of +1, equivalent to removing one electron from the system.'
half:
description: 'Core-hole treatment using a formal countercharge of +0.5, equivalent to removing half an electron from the system.'
SYSTEM:
tot_charge: 0.5
xch_fixed:
description: 'Core-hole treatment which places the excited electron into the conduction band (fixed occupations).'
SYSTEM:
occupations: fixed
tot_charge: 0
nspin: 2
tot_magnetization: 1
xch_smear:
description: 'Core-hole treatment which places the excited electron into the conduction band (smeared occupations).'
SYSTEM:
occupations: smearing
tot_charge: 0
sphuber marked this conversation as resolved.
Show resolved Hide resolved
nspin: 2
starting_magnetization(1): 0
none:
description: 'Applies no core-hole treatment (overrides the default tot_charge and changes it to 0).'
SYSTEM:
tot_charge: 0
17 changes: 17 additions & 0 deletions src/aiida_quantumespresso/workflows/protocols/xspectra/core.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
default_inputs:
abs_atom_marker: X
clean_workdir: True
get_powder_spectrum: False
run_replot: False
eps_vectors:
- [1., 0., 0.]
- [0., 1., 0.]
- [0., 0., 1.]
default_protocol: moderate
protocols:
moderate:
description: 'Protocol to perform XANES dipole calculations at normal precision and moderate computational cost.'
precise:
description: 'Protocol to perform XANES dipole calculations at high precision and higher computational cost.'
fast:
description: 'Protocol to perform XANES dipole calculations at low precision and minimal computational cost for testing purposes.'
Loading