please execute the cell below before starting the tutorial by selecting it and pressing Ctrl+Enter
%load_ext autoreload
%autoreload 2
# imports correct environment
from aiida import load_profile
load_profile()
# imports load_node()
from aiida.orm import load_node
# First we will import a prepared dataset for this tutorial with some structures and simulations
# If this was already executed, it will add nothing to the database
!verdi archive import ~/4.AiiDA-FLEUR/files/fleur_tutorial_data.aiida
Modifying a Fleur input file
To modify an existing FleurinpData
, we need to load it first. Please, do in via load_node()
function and proceed to the next section:
# you can modify this - insert a PK of any FleurinpData
fleurinp = load_node('780c0c59')
FleurinpModifier
The stored FleurinpData
can not be modified in-place because it was sealed when it was stored in the database. Therefore we always need to create a new FleurinpData
object to change an existing one.
To make changes and store the result in the database, AiiDA-Fleur contains a FleurinpModifier
class.
To start a process of FleurinpData
modification, we need to import the FleurinpModifier
class first and initialise an instance:
from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
fleurmode = FleurinpModifier(fleurinp)
Now we need to work with methods belonging to the class to perform a modification. One needs to do two steps:
- Register all required changes
- Apply them and store the result in the database
Registration methods
set_inpchanges()
Probably the simplest way to register a change is to use set_inpchanges()
that replaces known attributes. For this, one needs to pass a key: value dictionary into the method call. A key usually corresponds to the name of an attribute in the inp.xml
file. All supported attribute names can be found in the documentation.
To begin with, we want to set itmax
to 30
and minDistance
to 0.00002
:
fleurmode.set_inpchanges({'itmax': 30, 'minDistance' : 0.00002})
One can also provide a python dictionary with the parameter names and their values you would like to change:
change_dict = {
'dos' : True,
'minEnergy' : -0.8,
'maxEnergy' : 0.8,
'sigma' : 0.005,
}
fleurmode.set_inpchanges(change_dict)
a = fleurmode.changes()
changes preview
Note, the changes are in stock and not applied yet. You can make a preview of the resulting inp.xml
by:
a = fleurmode.show(validate=True) #display=False
validate=True
means the resulting inp.xml
will be validated against the schema: if you specify changes leading to corrupted inp.xml
file you will be informed. See an example below:
# If the changes are not valid we will get an error
fleurmode_fail = FleurinpModifier(fleurinp)
fleurmode_fail.set_inpchanges({'itmax': -10, 'minDistance' : 0.001})
fleurmode_fail.show(validate=True, display=False)
# or if you mistype a key
fleurmode_fail.undo()
fleurmode_fail.set_inpchanges({'itma': 10, 'minDistance' : 0.001})
fleurmode_fail.show(validate=True, display=False)
Methods for species manipulation
Change muffin tin radii, or any species parameters you have to parse a nested dict with the subtags
# the first argument specificies the species to modify. Here we choose the syntax 'all-<string>'
# This will modify all species containing the string in its name, here Si
fleurmode.set_species('all-Si', {'mtSphere' : {'radius' : 3.5, 'gridPoints' : 841},
'atomicCutoffs' : {'lmax' : 9, 'lnonsphr' : 6}})
See the result
fleurmode.show(validate=True)
Registered changes management
To print out the list of registered changes, run:
fleurmode.changes()
all these changes are not applied and we can revert them:
fleurmode.undo() # drops last registered change
fleurmode.changes()
fleurmode.undo()
fleurmode.changes()
Apply changes and store in the database
With freeze()
method we store a new FleurinpData
object in the database applying all registered changes. freeze()
return a stored FleurinpData
object:
fleurinp_modified = fleurmode.freeze()
print('The PK of the stored FleurinpData is {}'.format(fleurinp_modified.pk))
XML registration methods
FleurinpModifier
contains more general xml methods to deal with tags, attributes and text of an xml file.
They require some knoledge on the internal structure of the inp.xml
file, however, provide more general and flexible tools for inp.xml manipulation.
In this tutorial we will cover only a few existing methods, for all of them see the documentation.
The first example is changing itmax
in the inp.xml
file. We did it already via set_inpchanges()
methods above, but there is another way to do it:
xpathn = '/fleurInput/calculationSetup/scfLoop'
fleurmode.xml_set_attrib_value_no_create(xpathn, 'itmax', 29)
fleurmode.show(validate=True) # preview the result
There are also methods for creating new kpoint paths/meshes availiable. These are created using python libraries like ase
or spglib
. Below we create a kpoint mesh (including the gamma point) compatible with the symmetries in the inp.xml
fleurmode.set_kpointmesh((12,12,12), switch=True)
fleurmode.show(validate=True) # preview the result
Or a kpoint-path for calculating a bandstructure:
fleurmode.set_kpointpath('XKGLWXG', switch=True, nkpts=100)
fleurmode.show(validate=True) # preview the result
In conclusion, there are two types of registration methods: pre-defined and xml ones. Pre-defined changes already know where to find a certain attribute that a user wants to change. In contrast, XML methods can be more flexible because they require an xml path to work.
In next tutorial we are going to learn how to generate inp.xml
and corresponding FleurinpData
object using the inpgen
code.