Skip to content

Commit

Permalink
Merge pull request #117 from JuDFTteam/develop
Browse files Browse the repository at this point in the history
Release 1.1.13
  • Loading branch information
PhilippRue authored Mar 29, 2023
2 parents 914bdc4 + 67e2131 commit 19feee5
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 109 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.1.12
current_version = 1.1.13
commit = True
tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?
Expand Down
2 changes: 1 addition & 1 deletion aiida_kkr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
AiiDA KKR
"""

__version__ = '1.1.12'
__version__ = '1.1.13'
105 changes: 100 additions & 5 deletions aiida_kkr/calculations/kkr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import os
import numpy as np
from aiida.engine import CalcJob
from aiida.orm import CalcJobNode, load_node, RemoteData, Dict, StructureData, KpointsData, Bool
from aiida.orm import CalcJobNode, load_node, RemoteData, Dict, StructureData, KpointsData, Bool, FolderData
from .voro import VoronoiCalculation
from ..tools.common_workfunctions import get_natyp
from aiida.common.utils import classproperty
Expand All @@ -27,7 +27,7 @@
__copyright__ = (u'Copyright (c), 2017, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
__version__ = '0.12.2'
__version__ = '0.12.5'
__contributors__ = ('Jens Bröder', 'Philipp Rüßmann')

verbose = False
Expand Down Expand Up @@ -55,6 +55,7 @@ class KkrCalculation(CalcJob):
# List of optional input files (may be mandatory for some settings in inputcard)
_SHAPEFUN = 'shapefun' # mandatory if nonspherical calculation
_SCOEF = 'scoef' # mandatory for KKRFLEX calculation and some functionalities
_BFIELD = 'bfield.dat' # mandatory if <NONCOBFIELD>= True
_NONCO_ANGLES = 'nonco_angle.dat' # mandatory if noncollinear directions are used that are not (theta, phi)= (0,0) for all atoms
_NONCO_ANGLES_IMP = 'nonco_angle_imp.dat' # mandatory for GREENIMP option (scattering code)
_SHAPEFUN_IMP = 'shapefun_imp' # mandatory for GREENIMP option (scattering code)
Expand Down Expand Up @@ -101,6 +102,7 @@ class KkrCalculation(CalcJob):
_DECIFILE = 'decifile'
# BdG mode
_BDG_POT = 'den_lm_ir.%0.3i.%i.txt'
_BDG_CHI_NS = 'den_lm_ns_*.npy'

# template.product entry point defined in setup.json
_default_parser = 'kkr.kkrparser'
Expand Down Expand Up @@ -215,6 +217,25 @@ def define(cls, spec):
equal to the number of atoms.
"""
)
spec.input(
'bfield',
valid_type=Dict,
required=False,
help="""Non-collinear exteral B-field used for constraint calculations.
The Dict node should be of the form
initial_noco_angles = Dict(dict={
'theta': [theta_at1, theta_at2, ..., theta_atN],
# list theta values in degrees (0..180)
'phi': [phi_at1, phi_at2, ..., phi_atN],
# list phi values in degrees (0..360)
'magnitude': [magnitude at_1, ..., magnitude at_N]
# list of magnitude of the applied fields in Ry units
})
Note: The length of the theta, phi and magnitude lists have to be
equal to the number of atoms.
"""
)
spec.input(
'deciout_parent',
valid_type=RemoteData,
Expand All @@ -230,6 +251,15 @@ def define(cls, spec):
the kkrflex_* files are copied to the retrieved (can clutter the
database) or are ony left in the remote folder."""
)
spec.input(
'anomalous_density',
valid_type=FolderData,
required=False,
help="""FolderData that contains anomalous density input files for
the KKRhost BdG calculation. If these are not give the code looks
for them in the retrieved of the parent calculation and takes them
from there."""
)

# define outputs
spec.output(
Expand Down Expand Up @@ -295,6 +325,10 @@ def prepare_for_submission(self, tempfolder):
if 'initial_noco_angles' in self.inputs:
parameters = self._use_initial_noco_angles(parameters, structure, tempfolder)

# write bfield.dat file and add '<NONCOBFIELD>= True' to input parameters
if 'bfield' in self.inputs:
parameters = self._use_nonco_bfield(parameters, structure, tempfolder)

# activate decimation mode and copy decifile from deciout parent
if 'deciout_parent' in self.inputs:
parameters = self._use_decimation(parameters, tempfolder)
Expand Down Expand Up @@ -802,10 +836,13 @@ def _get_BdG_filelist(self, parameters, natom, nspin):
self.report(f'retrieve BdG? {retrieve_BdG_files}')

if retrieve_BdG_files:
# anomalous density files for all atoms if present
for iatom in range(natom):
for ispin in range(nspin):
print('adding files for BdG mode')
add_files += [self._BDG_POT % (iatom + 1, ispin + 1)]
# radially-averaged anomalous density matrix (for triplet components etc.)
add_files.append(self._BDG_CHI_NS)

#also retrieve BdG DOS files for anomalous density and hole part
for BdGadd in ['_eh', '_he', '_hole']:
Expand Down Expand Up @@ -1015,6 +1052,51 @@ def _use_initial_noco_angles(self, parameters, structure, tempfolder):

return parameters

def _use_nonco_bfield(self, parameters, structure, tempfolder):
"""
Set external non-collinear bfield (writes bfield.dat to tempfolder) used in constraint calculations.
"""
self.report('Found `bfield` input node, writing nonco_angle.dat file')

# extract number of atoms for length comparison
natom = get_natyp(structure)

change_values = [['<NONCOBFIELD>', True]]
parameters = _update_params(parameters, change_values)

# extract magnitude, theta and phi values from input node
mags = self.inputs.bfield['magnitude']
if len(mags) != natom:
raise InputValidationError(
'Error: `magnitude` list in `bfield` input node needs to have the same length as number of atoms!'
)
thetas = self.inputs.bfield['theta']
if len(thetas) != natom:
raise InputValidationError(
'Error: `theta` list in `bfield` input node needs to have the same length as number of atoms!'
)
phis = self.inputs.bfield['phi']
if len(phis) != natom:
raise InputValidationError(
'Error: `phi` list in `bfield` input node needs to have the same length as number of atoms!'
)

# now write kkrflex_angle file
with tempfolder.open(self._BFIELD, 'w') as bfield_file:
bfield_file.write('# theta [deg] phi [deg] magnitude [Ry]\n')
for iatom in range(natom):
theta, phi = thetas[iatom], phis[iatom]
magnitude = mags[iatom]
# check consistency
if theta < 0. or theta > 180.:
raise InputValidationError(
f'Error: theta value out of range (0..180): iatom={iatom}, theta={theta}'
)
# write line
bfield_file.write(f' {theta} {phi} {magnitude}\n')

return parameters

def _use_decimation(self, parameters, tempfolder):
"""
Activate decimation mode and copy decifile from output of deciout_parent calculation
Expand Down Expand Up @@ -1063,13 +1145,26 @@ def _copy_BdG_pot(self, retrieved, tempfolder):
Activate BdG mode and copy den_lm_ir files of the previous output to the input of this calculation.
"""

BDG_POT_FILES = [i for i in retrieved.list_object_names() if self._BDG_POT.split('.')[0] in i]
if 'anomalous_density' in self.inputs:
# this means we have a FolderData input that contains the
# anomalous density files
adens_folder = self.inputs.anomalous_density
else:
# if no anomalous density is given as an input node we check
# if there are any anomalous density files in the parent retrieved
# and take them from there if present
adens_folder = retrieved

# list of den_lm_ir files (anomalous density per atom)
BDG_POT_FILES = [i for i in adens_folder.list_object_names() if self._BDG_POT.split('.')[0] in i]

# add 'den-lm_ir' files to input
for BdG_pot in BDG_POT_FILES:
self.report(f'Copy BdG potential {BdG_pot}')
with retrieved.open(BdG_pot, 'r') as file_handle:
self.report(f'Copy BdG potential {BdG_pot} from {adens_folder.uuid}')
# read from parent
with adens_folder.open(BdG_pot, 'r') as file_handle:
file_txt = file_handle.readlines()
# write to tempfolder
with tempfolder.open(BdG_pot, 'w') as file_handle:
file_handle.writelines(file_txt)

Expand Down
1 change: 1 addition & 0 deletions aiida_kkr/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .kick_out_core_states import *
from .neworder_potential import *
from .find_parent import get_calc_from_remote, get_remote, get_parent
from .bdg_tools import get_anomalous_density_data


# expose structure finder from VoronoiCalculation
Expand Down
48 changes: 48 additions & 0 deletions aiida_kkr/tools/bdg_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
Helper tools that deal with the anomalous density of the BdG formalism in KKR
"""

from aiida.engine import calcfunction
from aiida.orm import FolderData


@calcfunction
def get_anomalous_density_data(retrieved, rename_files=None):
"""
Extract anomalous density files from a retrieved folder of a KkrCalculation
and copy into a new FolderData. This FolderData is then returned and can be
used as the anomalous_density FolderData input to a KkrCalculation.
:param retrieved: retrieved FolderData of a parent KKRhost BdG calculation where anomalous density files are stored (called `den_lm_ir.AAA.1.txt` where AAA is an atom index)
:param rename_files: Optional Dict node where mappings of file names are defined. This is helpful if the atom index in the new structure is different from the original calculation (e.g. atom N of the original structure corresponds to atom M of the new structure, then the renaming dict should be {N: M}). Indices that are not found or that map to None are skipped and will not appear in the returned FolderData!
:returns: anomalous_density FolderData which contains the (possibly renamed) anomalous density files
"""
BdG_files = [i for i in retrieved.list_object_names() if 'den_lm_ir' in i]

anomalous_density = FolderData()
for fname in BdG_files:
with retrieved.open(fname, 'r') as _fin:
# default is to use the same name as in the input
fname_out = fname

# rename file, if natom is found in the renaming dict
if rename_files is not None:
# find atom index (should be integer)
natom = int(fname.split('.')[1])
# we pick the new atom index and recreate the filename
natom_new = {int(k): v for k, v in rename_files.get_dict().items()}.get(natom)
if natom_new is None:
# if no renaming is mapping is found
# we do not copy this anomalous density but leave it out
fname_out = None
else:
# construct changed name
fname_out = 'den_lm_ir.%0.3i.1.txt' % natom_new

if fname_out is not None:
# copy input file to FolderData node, maybe with changed name
anomalous_density.put_object_from_filelike(_fin, fname_out)

return anomalous_density
4 changes: 2 additions & 2 deletions aiida_kkr/tools/plot_kkr.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
__copyright__ = (u'Copyright (c), 2018, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
__version__ = '0.7.0'
__version__ = '0.7.1'
__contributors__ = ('Philipp Rüßmann')


Expand Down Expand Up @@ -1896,7 +1896,7 @@ def get_ef_from_parent(node):
except:
with node.outputs.retrieved.open('output.0.txt', mode='r') as file_handle:
txt = file_handle.readlines()
iline = search_string('Fermi energy', txt)
iline = search_string('Fermi energy =', txt)
if iline >= 0:
ef = txt[iline].split('=')[1]
ef = float(ef.split()[0])
Expand Down
Loading

0 comments on commit 19feee5

Please sign in to comment.