From 2934630c0d7bde09e85407490cb1b7477db93c05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20R=C3=BC=C3=9Fmann?=
Date: Wed, 22 Nov 2023 08:08:25 +0000
Subject: [PATCH] Add feature to write kkrflex_rimpshift file
---
aiida_kkr/calculations/kkrimp.py | 56 +++++++++++++++++++++++++---
aiida_kkr/tools/combine_imps.py | 5 ++-
aiida_kkr/workflows/_combine_imps.py | 2 +-
aiida_kkr/workflows/gf_writeout.py | 2 +-
aiida_kkr/workflows/imp_BdG.py | 4 +-
aiida_kkr/workflows/kkr_imp_sub.py | 2 +-
6 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/aiida_kkr/calculations/kkrimp.py b/aiida_kkr/calculations/kkrimp.py
index f4d6b392..e46409cf 100644
--- a/aiida_kkr/calculations/kkrimp.py
+++ b/aiida_kkr/calculations/kkrimp.py
@@ -22,7 +22,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.9.1'
+__version__ = '0.10.0'
__contributors__ = (u'Philipp Rüßmann', u'Fabian Bertoldo')
#TODO: implement 'ilayer_center' consistency check
@@ -50,6 +50,7 @@ class KkrimpCalculation(CalcJob):
_KKRFLEX_ANGLE = u'kkrflex_angle'
_KKRFLEX_LLYFAC = u'kkrflex_llyfac'
_KKRFLEX_SOCFAC = u'kkrflex_spinorbitperatom'
+ _KKRFLEX_RIMPSHIFT = u'kkrflex_rimpshift'
# full list of kkrflex files
_ALL_KKRFLEX_FILES = KkrCalculation._ALL_KKRFLEX_FILES
@@ -147,13 +148,14 @@ def define(cls, spec):
required=False,
help="""
Settings for running a LDA+U calculation. The Dict node should be of the form
- settings_LDAU = Dict(dict={'iatom=0':{
+ settings_LDAU = Dict({'iatom=0':{
'L': 3, # l-block which gets U correction (1: p, 2: d, 3: f-electrons)
'U': 7., # U value in eV
'J': 0.75, # J value in eV
'Eref_EF': 0., # reference energy in eV relative to the Fermi energy. This is the energy where the projector wavefunctions are calculated (should be close in energy where the states that are shifted lie (e.g. for Eu use the Fermi energy))
}})
- Note: you can add multiple entries like the one for iatom==0 in this example. The atom index refers to the corresponding atom in the impurity cluster.
+
+Note: you can add multiple entries like the one for iatom==0 in this example. The atom index refers to the corresponding atom in the impurity cluster.
"""
)
spec.input(
@@ -163,12 +165,26 @@ def define(cls, spec):
help="""
Initial non-collinear angles for the magnetic moments of the impurities. These values will be written into the `kkrflex_angle` input file of KKRimp.
The Dict node should be of the form
- initial_noco_angles = Dict(dict={
+ initial_noco_angles = 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)
'fix_dir': [True, False, ..., True/False], # list of booleans indicating of the direction of the magentic moment should be fixed or is allowed to be updated (True means keep the direction of the magnetic moment fixed)
})
- Note: The length of the theta, phi and fix_dir lists have to be equal to the number of atoms in the impurity cluster.
+
+Note: The length of the theta, phi and fix_dir lists have to be equal to the number of atoms in the impurity cluster.
+"""
+ )
+ spec.input(
+ 'rimpshift',
+ valid_type=Dict,
+ required=False,
+ help="""
+Shift for atoms in the impurity cluster used in U-transformation.
+
+The Dict node should be of the form
+ rimpshift = Dict({'shifts': [[0., 0., 0.], ... ]})
+
+Note: The length of the 'shifts' attribute should be an array with three numbers indicating the shift for each atom in the impurity cluster.
"""
)
@@ -222,6 +238,9 @@ def prepare_for_submission(self, tempfolder):
self._OUT_ENERGYSP_PER_ATOM, self._OUT_ENERGYTOT_PER_ATOM
]
+ # maybe create kkrflex_rimpshift file
+ self._write_kkrflex_rimpshift(tempfolder, parameters)
+
# extract run and test options (these change retrieve list in some cases)
allopts = self.get_run_test_opts(parameters)
@@ -845,7 +864,7 @@ def _write_kkrflex_angle(self, parameters, GFhost_folder, tempfolder):
# check if calculation is no Jij run
if parameters.get_value('CALCJIJMAT') is not None and parameters.get_value('CALCJIJMAT') == 1:
- raise InputValidationError('ERROR: ')
+ raise InputValidationError('ERROR: angles cannot be set if Jij mode is chosen!')
# extract NATOM from atominfo file
natom = self._get_natom(GFhost_folder)
@@ -881,6 +900,31 @@ def _write_kkrflex_angle(self, parameters, GFhost_folder, tempfolder):
# write line
kkrflex_angle_file.write(f' {theta} {phi} {fix_dir}\n')
+ def _write_kkrflex_rimpshift(self, tempfolder, parameters):
+ """Create the kkrflex_rimpshift file in tempfolder for U-transformation"""
+
+ if 'rimpshift' in self.inputs:
+ # check if calculation is no Jij run
+ if parameters.get_value('LATTICE_RELAX') is not None and parameters.get_value('LATTICE_RELAX') != 1:
+ raise InputValidationError('ERROR: "LATTICE_RELAX" in the input parameters needs to be set to 1.')
+
+ # extract NATOM from atominfo file
+ natom = self._get_natom(tempfolder)
+
+ # extract values from input node
+ rimpshift = self.inputs.rimpshift['shifts']
+ if len(rimpshift) != natom:
+ raise InputValidationError(
+ 'Error: `shifts` list in `rimpshift` input node needs to have the same length as number of atoms in the impurity cluster!'
+ )
+
+ # now write kkrflex_rimpshift file
+ with tempfolder.open(self._KKRFLEX_RIMPSHIFT, 'w') as kkrflex_rimpshift_file:
+ for iatom in range(natom):
+ shift = rimpshift[iatom]
+ # write line
+ kkrflex_rimpshift_file.write(f' {shift[0]} {shift[1]} {shift[2]}\n')
+
def _check_key_setting_consistency(self, params_kkrimp, key, val):
"""
Check if key/value pair that is supposed to be set is not in conflict with previous settings of parameters in params_kkrimp
diff --git a/aiida_kkr/tools/combine_imps.py b/aiida_kkr/tools/combine_imps.py
index 1e88b367..ad349ed5 100644
--- a/aiida_kkr/tools/combine_imps.py
+++ b/aiida_kkr/tools/combine_imps.py
@@ -88,7 +88,7 @@ def make_potfile_sfd(**kwargs):
# Create a SinglefileData node
SinglefileData = DataFactory('singlefile')
- out_potential_content = retrieved.get_object_content("out_potential")
+ out_potential_content = retrieved.get_object_content('out_potential')
# Create a temporary file
temp_dir = tempfile.gettempdir()
@@ -101,9 +101,10 @@ def make_potfile_sfd(**kwargs):
# Remove the temporary file
os.remove(temp_file)
-
+
return potfile_sfd
+
def extract_potfile_from_retrieved(retrieved):
"""
get output potential single file data from retrieved files or reuse existing
diff --git a/aiida_kkr/workflows/_combine_imps.py b/aiida_kkr/workflows/_combine_imps.py
index 7531a3a1..60d18374 100644
--- a/aiida_kkr/workflows/_combine_imps.py
+++ b/aiida_kkr/workflows/_combine_imps.py
@@ -746,7 +746,7 @@ def run_kkrimp_scf(self):
builder.options = self.inputs.scf.options
if 'wf_parameters' in self.inputs.scf:
builder.wf_parameters = self.inputs.scf.wf_parameters
- if 'params_overwrite' in self.inputs.scf :
+ if 'params_overwrite' in self.inputs.scf:
builder.params_overwrite = self.inputs.scf.params_overwrite
# take care of LDA+U settings
diff --git a/aiida_kkr/workflows/gf_writeout.py b/aiida_kkr/workflows/gf_writeout.py
index c1b00554..831e470f 100644
--- a/aiida_kkr/workflows/gf_writeout.py
+++ b/aiida_kkr/workflows/gf_writeout.py
@@ -89,7 +89,7 @@ def define(cls, spec):
super(kkr_flex_wc, cls).define(spec)
spec.input('kkr', valid_type=Code, required=False)
- spec.input('options', valid_type=Dict, required=False)#, default=lambda: Dict(dict=cls._options_default))
+ spec.input('options', valid_type=Dict, required=False)
spec.input('wf_parameters', valid_type=Dict, required=False)
spec.input('remote_data', valid_type=RemoteData, required=True)
spec.input('impurity_info', valid_type=Dict, required=True)
diff --git a/aiida_kkr/workflows/imp_BdG.py b/aiida_kkr/workflows/imp_BdG.py
index 02afa335..791de8b9 100644
--- a/aiida_kkr/workflows/imp_BdG.py
+++ b/aiida_kkr/workflows/imp_BdG.py
@@ -155,7 +155,7 @@ def define(cls, spec):
required=False,
help='Parent folder of previously converged host normal state KkrCalculation'
)
-
+
spec.input(
'imp_scf.remote_data_gf',
valid_type=RemoteData,
@@ -438,7 +438,7 @@ def DOS_calc(self):
if 'kkr' in self.inputs.dos.gf_writeout:
builder.kkr = self.inputs.dos.gf_writeout.kkr
if 'params_kkr_overwrite' in self.inputs.dos.gf_writeout:
- builder.gf_writeout.params_kkr_overwrite = self.inputs.dos.gf_writeout.params_kkr_overwrite
+ builder.gf_writeout.params_kkr_overwrite = self.inputs.dos.gf_writeout.params_kkr_overwrite # pylint: disable=no-member
if 'host_remote' in self.inputs.dos.gf_writeout:
builder.host_remote = self.inputs.dos.gf_writeout.host_remote
if 'options' in self.inputs.dos.gf_writeout:
diff --git a/aiida_kkr/workflows/kkr_imp_sub.py b/aiida_kkr/workflows/kkr_imp_sub.py
index ca767bd2..e34287be 100644
--- a/aiida_kkr/workflows/kkr_imp_sub.py
+++ b/aiida_kkr/workflows/kkr_imp_sub.py
@@ -118,7 +118,7 @@ def define(cls, spec):
spec.input('remote_data_Efshift', valid_type=RemoteData, required=False)
spec.input('kkrimp_remote', valid_type=RemoteData, required=False)
spec.input('impurity_info', valid_type=Dict, required=False)
- spec.input('options', valid_type=Dict, required=False) #, default=lambda: Dict(dict=cls._options_default))
+ spec.input('options', valid_type=Dict, required=False)
spec.input('wf_parameters', valid_type=Dict, required=False, default=lambda: Dict(dict=cls._wf_default))
spec.input(
'settings_LDAU', valid_type=Dict, required=False, help='LDA+U settings. See KKRimpCalculation for details.'