Optimisation of the lmf basis set
lmfa srtio3
lmf -vnk=2 srtio3 --rdbasp:fn=atm
lmf -vnk=2 srtio3 --optbas:sort:etol=.001
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012 --rdbasp:fn=atm
cp basp2.srtio3 basp.srtio3
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012 --rdbasp
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012 -vbigbas=t
This tutorial shows how to optimize the basis set for SrTiO3. The input file ctrl.srtio3 found in directory doc/FPsamples. (Output files are also in this directory.) It assumes you have read the FP documentation and the ASA documentation. This tutorial’s purpose is limited to demonstration of the automatic basis optimization option in lmf.
To follow this tutorial, start in the top-level directory. Copy the file doc/FPsamples/ctrl.srtio3 to this directory. In addition to making each sphere self-consistent, program lmfa also finds parameters RSMH and EH for each occupied orbital of each free atom, by minimizing the free-atom total energy. While this is not in general an optimum basis for the solid, it provides a reasonable choice, and thus a reasonable starting guess. You may tell lmf to read parameters of a basis from a separate input file, overriding the parameters specified in the ctrl file. Do this using token --rdbasp[:fn=name]
. The part in brackets is optional, and can be used to specify which file the parameters for the basis set are to be read from. If you don’t specify a name, lmf uses file basp (an extension is automatically appended to the name) In this case, we will use as starting values parameters generated by lmfa, which stores the data in file atm.srtio3. Note that the input file uses local orbitals for the Ti p and Sr p orbitals. (see input files, tokens PZ=0,4.9 for Sr and PZ=0,3.9 for Ti.
We begin by invoking lmfa:
lmfa srtio3
which makes each sphere self-consistent, and stores the free-atom data in file atm.srtio3 along with the parameters RSMH and EH it determined for the free atom. The latter data is found at the end of file atm.srtio3 :
BASIS:
Sr RSMH= 3.1 1.185 1.873 -1 EH= -0.114 -1.202 -0.1 0
Ti RSMH= 2.335 0.815 1.137 -1 EH= -0.12 -2.057 -0.1 0
O RSMH= 0.854 0.767 -1 EH= -1.289 -0.33 0
Note that the starting values EH for the Sr and Ti p orbitals are very deep. This is because turning on local orbitals in these channels causes lmfa to treat these channels (Sr 4p and Ti 3p) as valence states. lmfa also restricts RSMH not to exceed the MT radius for any orbital; that is why RSMH for the Sr s orbital is 3.1.
At this point we can carry out an optimization by minimizing the total energy using the Harris-Foulkes functional of the (non-self-consistent) density constructed out of a superposition of free-atom densities (Mattheis construction). Instead of doing that, let’s make the density self-consistent using the basis generated by lmfa. We use a very small number of k-divisions because we are only interested in a potential resembling the potential of the crystal, for purposes of finding an optimum basis. The Mattheis construction for oxides is a little too crude because of the large charge transfer effects.
lmf -vnk=2 srtio3 --rdbasp:fn=atm
The output can be found in FPsamples/out.srtio3.lmf0.
Now we can optimize the basis using this (approximately self-consistent) density. Once again, there is little point in converging everything to a high precision. We use 2 k-divisions as before. To tell lmf to optimize the basis, use a command-line switch --optbas
. When --optbas
is invoked, lmf will not attempt to make the output density, but instead just computes the Harris-Foulkes total energy while varying basis parameters you specify until an optimum is reached. The optimizer is not sophisticated; it minimizes the energy varying one parameter at a time, running through all the parameters you specify. This means that the order of optimization matters somewhat, though in practice it doesn’t seem to matter much. The syntax for optimization is
--optbas[:sort][:etol=#][:spec=spec-name[,rs][,e][,l=list]:spec=...]
Some notes about the syntax of --optbas
:
- You tell lmf whether to optimize wrt to RSMH by using ,rs or EH by using ,e. You can specify both by e,g. for species O, use
:spec=O,rs,e,...
- If no species are specified,
--optbas
will optimize all RSMH for all species, leaving EH untouched. - You specify which l orbitals to optimize using ,
l=list
. Here “list” consists of a list of integers strung together. For example, to optimize the O RSM for both s and p orbitals, use:spec=O,rs,l=01
. - Optional
:sort
tells lmf to choose for itself the order in which parameters are taken for optimization. It will pick smoothing radii first, because usually the total energy is more sensitive to RSMH than to EH. It orders the parameters from smallest (which correspond to more atomic-like states) to largest because the total energy is more sensitive to small-RSM orbitals. - Optional
:etol=#
tells lmf to keep the original value of the parameter unless the energy gain (by optimizing the parameter) exceeds #.
If you are not interested in refinements, but just want to get on with it, try
lmf -vnk=2 srtio3 --optbas:sort:etol=.001
To show a more interesting case, let’s optimize wrt most of the orbitals we have. (With only 1 irreducible k-point, lmf runs pretty fast.) Note that we still need to read the basis from file atm.
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012 --rdbasp:fn=atm
Early in the output you should see the following table:
LMFOPB: optimizing energy wrt 16 parameters:
spec | l | type | start |
---|---|---|---|
3:O | 1 | rsm | 0.767 |
2:Ti | 1 | rsm | 0.815 |
3:O | 0 | rsm | 0.854 |
2:Ti | 2 | rsm | 1.137 |
1:Sr | 1 | rsm | 1.185 |
1:Sr | 2 | rsm | 1.873 |
2:Ti | 0 | rsm | 2.335 |
1:Sr | 0 | rsm | 3.100 |
2:Ti | 1 | eh | -2.057 |
3:O | 0 | eh | -1.289 |
1:Sr | 1 | eh | -1.202 |
3:O | 1 | eh | -0.330 |
2:Ti | 0 | eh | -0.120 |
1:Sr | 0 | eh | -0.114 |
2:Ti | 2 | eh | -0.100 |
1:Sr | 2 | eh | -0.100 |
lmf optimizes the total energy wrt each variable, in order shown. (lmf changed the order because of the :sort
option). The output can be found in out.srtio3.lmfopt
The part of the output connected with basis optimization can be found in lines beginning with LMFOPB e.g.
LMFOPB: continue optimization of var #2, species Ti val=0.888867
MNBRAK: found=T x,f= 0.81500000 -2.65965498
MNBRAK: found=T x,f= 1.01500000 -2.65785139
MNBRAK: found=T x,f= 0.93860680 -2.65933813
MNBRAK: found=T x,f= 0.86163389 -2.65967351
BRENT: found=T x,f= 0.88886657 -2.65963089
LMFOPB: var #2 converged in 5 iterations to 0.862: ehf=-2.659674 ... writing file basp
After optimization is complete, lmf will (1) write the optimized basis to file basp*.srtio3, (2) print out how much the energy changed on account of the optimization:
LMFOPB: before optimization ehf=-2.5815\. After optimization ehf=-2.7009
and exit.
Copy the basp*.srtio3 file to basp.srtio3:
cp basp*.srtio3 basp.srtio3
Where * is some number. You may find that your basp file doesn’t have a number in which case you don’t have to do anything.
You might repeat this optimization, since the optimization consisted of a series of independent optimizations one followed after another. In that case, don’t read the basis from the file atm but from file basp:
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012 --rdbasp
After the second optimization, the energy changes to:
LMFOPB: before optimization ehf=-2.7011.
After optimization ehf=-2.7203
Repeating the optimization still once more lowers the energy slightly:
LMFOPB: before optimization ehf=-2.7211.
After optimization ehf=-2.7267
File basp contains a reasonably optimized basis:
BASIS:
Sr RSMH= 3.1 1.345 2.013 EH= -0.02 -1.175 -0.518
Ti RSMH= 0.9 0.962 1.142 EH= -0.02 -2.597 -0.411
O RSMH= 0.922 0.802 EH= -1.104 -0.02
It is interesting to compare this basis to the initial one selected by lmfa.
You can use your text editor to cut and paste this basis into your ctrl file. Alternatively you can carry around file basp.srtio3 and always remember to invoke lmf with --basp
.
The procedure just outlined has the advantage that it is completely automatic. However, there are a couple of pitfalls. There is a possibility that it will get stuck in local minima. Also, some orbitals, e.g. the Sr d orbital and the O p orbitals have no occupation in the free atom, so they were left out of the basis. They do, however, contribute in a non-negligible way to the energy. Optimizing the basis with these orbitals included generates the following
BASIS:
Sr RSMH= 0.948 1 1.847 1 EH= -0.086 -1.046 -0.347 -0.1
Ti RSMH= 1 0.8 1.052 0 EH= -0.073 -2 -0.279 0
O RSMH= 0.899 0.8 2.4 EH= -0.956 -0.065 -0.1
This was obtained by using the basis supplied by the input file, and optimizing it:
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012
It produced
LMFOPB: before optimization ehf=-2.7507\. After optimization ehf=-2.7607
One could go further, choosing a still larger basis (one is supplied by the input file, which is used if you invoke lmf with -vbigbas=t
)
lmf -vnk=2 srtio3 --optbas:sort:spec=O,rs,e,l=01:spec=Ti,rs,e,l=012:spec=Sr,rs,e,l=012 -vbigbas=t
which produced
LMFOPB: before optimization ehf=-2.7711\. After optimization ehf=-2.7888
This energy (-2.7888 Ry), is not so much larger than the minimal-basis energy (-2.7267) — it is deeper by 12 mRy/atom. Thus, the minimal basis is quite reasonable.