Subsections

1 Providing the input

At first, you have to create the input for the code. DFTB+ accepts either Human-readable Structured Data (HSD) or eXtended Markup Language (XML) input. In this tutorial HSD will be used, and in this case the input file must be called dftb_in.hsd. The input file used in this howto looks as follows: (You can obtain this file by downloading the provided tar.gz archive for this howto from the howto overview page.)

Geometry = GenFormat {
3  C
 O H
     1    1    0.00000000000E+00  -0.10000000000E+01   0.00000000000E+00
     2    2    0.00000000000E+00   0.00000000000E+00   0.78306400000E+00
     3    2    0.00000000000E+00   0.00000000000E+00  -0.78306400000E+00
}

Driver = ConjugateGradient {
  MovedAtoms = Range { 1 -1 }
  MaxForceComponent = 1.0e-4
  MaxSteps = 100
  OutputPrefix = "geom.out"
}

Hamiltonian = DFTB {
  SCC = Yes
  SCCTolerance = 1.0e-5
  MaxSCCIterations = 1000
  Mixer = Broyden {
    MixingParameter = 0.2
  }
  SlaterKosterFiles = {
    O-O = "O-O.skf"
    O-H = "O-H.skf"
    H-O = "O-H.skf"
    H-H = "H-H.skf"
  }
  MaxAngularMomentum = {
    O = "p"
    H = "s"
  }
  Charge = 0.0
  SpinPolarisation = {}
  Filling = Fermi {
    Temperature [Kelvin] = 0.0
  }
}

Options = {}

ParserOptions = {
  ParserVersion = 3
}

The order of the specified properties in the HSD input is arbitrary. You are free to capitalise the keywords and physical units as you like, since they are case-insensitive. This is not valid, however, for string values, especially if they are specifying file names.

1.1 Geometry

The Geometry property contains the types and coordiantes of the atoms in your system. The geometry of the system in the sample input file is provided in the so called "gen" format, which was the traditional geometry input format of the DFTB method. The formal description of this format can be found in the DFTB+ manual. The current example

Geometry = GenFormat {
  3  C   # Cluster with 3 atoms
   O H   # Two elements, 1 - O, 2 - H
  #  Index Type  Coordinates
       1    1    0.00000000000E+00  -0.10000000000E+01   0.00000000000E+00
       2    2    0.00000000000E+00   0.00000000000E+00   0.78306400000E+00
       3    2    0.00000000000E+00   0.00000000000E+00  -0.78306400000E+00
}
specifies a cluster system with 3 atoms of the type O and H. The coordinates of the atoms in the "gen" format are given in Angstroms. The first column of integers contains the sequential number of the atoms in the sytem (ignored by the parser). The second column contains the type of each atom, given as the position of the appropriate element in the element list in the second line. The GenFormat{} is not the only method to specify the geometry, you should check the manual for other methods.

As demonstrated above, it is possible to put arbitrary comments in the HSD input after a hashmark (#) character. Everything between the hash and the end of the line is ignored by the parser.

Very often, the geometry is stored in an external file different from dftb_in.hsd. To save you the copying and pasting from that file into the input file, you can use the file inclusion feature of the HSD format:

Geometry = GenFormat {
  <<< "input_geometry.gen"
}
The <<< operator includes the specified file as raw data. (The file is not checked for any HSD constructs.) In the example above, the file input_geometry.gen must be in gen format of course.

1.2 Driver

After having specified the geometry of your system, you should decide, what to do with that geometry. The Driver property determines, how the geometry should be changed (if at all) during the run. If you only would like to make a static calculation, you must set it to an empty value like

  Driver = {}   # Empty value for the driver

In the current example, however,

# Do conjugate gradient optimisation
Driver = ConjugateGradient {
  MovedAtoms = Range { 1 -1 }     # Move all atoms in the system
  MaxForceComponent = 1.0e-4      # Stop if maximal force below 1.0e-4
  MaxSteps = 100                  # Stop after maximal 100 steps
  OutputPrefix = "geom.out"       # Final geometry in geom.out.{xyz,gen}
}
the molecule is relaxed using the conjugate gradient method. The entire range of atoms from the first (1) until and including the last one (-1) is allowed to move. Instead of Range { 1 -1 } you could also have written
  MovedAtoms = Range { 1 3 }   # Atoms from the 1st until the 3rd
or
  MovedAtoms = { 1 2 3 }       # Explicitely listing the atoms to move

In our case the geometry optimisation continues as long as the maximal force component is bigger than 1e-4 atomic units (Hartree/Bohr). Numeric values are per default interpreted in atomic units. The HSD format offers, however, the possibility to use alternative units by specifying the unit (modifier) of the value in square brackets before the equal sign. For example instead of the original specification, you could have used

  MaxForceComponent [eV/AA] = 5.14e-3  # Force in Electronvolt/Angstrom
or
  MaxForceComponent [Electronvolt/Angstrom] = 5.14e-3

The MaxSteps property specifies, after how many geometry optimisation steps the program should stop, even if the specified tolerance for the maximal force component could not reached.

Finally, the OutputPrefix property specifies the name of the file containing the actual geometry during the optimisation (end the final geometry at the end of the calculation). The geometry is written in gen and xyz formats to the files obtained by appending ".gen" and ".xyz" suffixes to the specified name (geom.out.gen and geom.out.xyz in our case).

1.3 Hamiltonian

In order to calculate the various properties of your system, you have to decide upon the way how the Hamiltonian for your system should be built. At the moment DFTB+ eases the decision quite a lot, since it only supports a Density Functional based Tight Binding Hamiltonian (with some extensions). In our example, the chosen self-consistent DFTB Hamiltonian has the following properties:

Hamiltonian = DFTB {               # DFTB Hamiltonian
  SCC = Yes                        # Use self consistent charges
  SCCTolerance = 1.0e-5            # Tolerance for charge consistence
  MaxSCCIterations = 1000          # Nr. of maximal SCC iterations
  Mixer = Broyden {                # Broyden mixer for charge mixing
    MixingParameter = 0.2          # Mixing parameter
  }
  SlaterKosterFiles = {               # Specifying Slater-Koster files
    O-O = "O-O.skf"
    O-H = "O-H.skf"
    H-O = "O-H.skf"
    H-H = "H-H.skf"
  }
  MaxAngularMomentum = {           # Maximal l-value of the various species
    O = "p"
    H = "s"
  }
  Charge = 0.0                        # System neutral
  SpinPolarisation = {}               # No spin polarisation
  Filling = Fermi {                   # No temperature
    Temperature [Kelvin] = 0.0
  }
}

In this example the SCC-DFTB method is used for building up the Hamiltonian (and calculating the total energy, forces, etc.). The charges are considered to be converged if the difference between the charges using to build the Hamiltonian and the charges obtained after the diagonalisation of the Hamiltonian is below 1e-5. If the convergence is not reached within the specified number of cycles (MaxSCCIterations), the code calculates the total energy using the charges obtained so far. (Appropriate warning messages are printed out.)

In order to damp charge oscillations and to speed up convergence, the charges of the subsequent iterations are mixed together. The Mixer property specifies the type of mixer to use. The mixers usually requires further properties, like the mixing factor for the Broyden mixer above.

The integral tables (together with other atomic and diatomic parameters) necessary for the build up of the Hamiltonian are stored in the so called Slater-Koster files. Those files always describe the interaction between atom pairs. Therefore, you have to specify for every atom pair the corresponding Slater-Koster file.

  SlaterKosterFiles = {               # Specifying Slater-Koster files
    O-O = "O-O.skf"
    O-H = "O-H.skf"
    H-O = "O-H.skf"
    H-H = "H-H.skf"
  }

If you are using a certain file name convention, you can avoid typing all the file names by specifying only the generating pattern. The input

  SlaterKosterFiles = Type2FileNames {   # File names with two atom type names
    Prefix = ""             # No prefix before first type name
    Separator = "-"         # Dash between type names
    Suffix = ".skf"         # Suffix after second type name
}
would generate exactly the same file names as in the example above. If the Slater-Koster files are in a different directory as the input file dftb_in.hsd, you can append the path as prefix:
  SlaterKosterFiles = Type2FileNames {    # File names from two atom type names
    Prefix = "/home/aradi/slako/mio-0-1"  # Path as prefix
    Separator = "-"         # Dash between type names
    Suffix = ".skf"         # Suffix after second type name
}

The historical Slater-Koster file format does not contain any information about the orbitals, which were considered when generating the interaction tables. Therefore, you must provide the highest angular momentum for every element as s, p, d or f. This information can be obtained from the documentation of the Slater-Koster files. In the distributed standardised sets (as distributed on dftb.org) this information is contained in the documentation appended to the end of each SK-file.

The charge of the system (Charge) can be specified as real number. It's the real total charge of your system, so that negative numbers mean excess electrons in the system.

For the spin polarisation you have to specify the type of the spin polarisation to use. If you don't need spin polarisation, you should assign the empty value to it:

  SpinPolarisation = {}
If you wanted to make a spin polarised calculation with colinear spins, you should write something like
  SpinPolarisation = Colinear {
    UnpairedElectrons = 2.0    # Magnitude of the spin polarisation
  }
In that latter case you would also have to specify the spin coupling constants in the SpinConstants property. (See the manual for details.)

Finally, the Filling property describes the method to use for filling up the one electron levels with electrons. The filling functions usually require further parameters (e.g the temperature).

1.4 Options

The Options property contains a few global settings for the code. In the current example, no options are specified, so that the empty value is assigned to that property:

  Options = {}
You could even leave out this line, since the default value for the Options property is the empty value anyway.

1.5 ParserOptions

This block contains options which are interpreted by the parser itself and are not passed to the main program. The most important of those options is the ParserVersion option, which tells the parser, for which parser the current input file was created for. If this is not the current parser but an older one, this allows backwards compatibility.

The version number of the parser in the current DFTB+ code is always printed out at the program start. It is a good habit to set this value in your input files explicitely, like in our case

  ParserVersion = 3
It allows you namely to use your input file with the future versions of DFTB+ without adapting it by hand, if the input format changed in the new versions.