Preparation of reference data

Throughout the tutorial we will be using reference data for training and comparison. The present section provides a short description of the code to generate these data.

General preparations

We first set a few parameters that define the structures to be generated. This includes

  • the size of the supercell (cell_size),
  • the number of structures (number_of_structures),
  • the standard deviation of the distribution of displacements (rattle_std),
  • the minimum separation of any two atoms in the “rattled” structures (minimum_distance), and
  • the name of the output file (structures_fname).

In addition, we specify a primitive structure and an ASE calculator object. For simplicity, here, we will employ the very simple effective medium theory (EMT) calculator provide by ASE. In practice, one would commonly resort to higher quality method such as density functional theory (DFT).

'''
Prepare training structures for FCC-Ni using an EMT calculator and a
Monte Carlo rattle approach for generating displacements.

Runs in approximately 10 seconds on an Intel Core i5-4670K CPU.
'''

import os
from ase.io import write
from ase.build import bulk
from ase.calculators.emt import EMT
from hiphive.structure_generation import generate_mc_rattled_structures


# parameters
structures_fname = 'structures/rattled_structures.extxyz'
number_of_structures = 5
cell_size = 4
rattle_std = 0.03
minimum_distance = 2.3

# setup
atoms_ideal = bulk('Ni', cubic=True).repeat(cell_size)
calc = EMT()

Structure generation

One could easily generate structures with randomized displacements by drawing components of the atomic displacement vector from a normal distribution with a specific standard deviation (rattle_std). This procedure, however, tends to produce structures with some very large forces, which poorly mimic the distribution of forces observed in molecular dynamics simulations. This behavior occurs since the _uncorrelated_ application of displacements can lead to very short interatomic distances as shown in the following figure. Such situations are heavily penalized in e.g., MD simulations because of the steep repulsive interaction.

../_images/structure_generation_distributions1.svg

Distribution of forces for structures obtained by molecular dynamics (MD) simulation, standard rattle, as well as the Monte Carlo rattle procedure implemented by the generate_mc_rattled_structures function. The scripts used for generating data and figure can be found in an example of the advanced topics section.

The generate_mc_rattled_structures function provides a means to overcome this issue. It implements a simple Monte Carlo procedure, which enforces a lower limit on any interatomic distance in the final structure (minimum_distance). Here, it is used to generate structures with randomized displacements. A more detailed discussion of this subject can be found here.

Warning

Please note that calling functions that rely on the generation of pseudo- random numbers repeatedly with the same seed (i.e., repeatedly falling back to the default value) is strongly discouraged as it will lead to correlation. To circumvent this problem one can for example seed a sequence of random numbers and then use these numbers in turn as seeds.

For each randomized structure we then compute the atomic forces. The final set of structures is written to file for later use.

structures = generate_mc_rattled_structures(
    atoms_ideal, number_of_structures, rattle_std, minimum_distance)
for structure in structures:
    structure.set_calculator(calc)
    forces = structure.get_forces()

    displacements = structure.positions - atoms_ideal.get_positions()
    structure.new_array('displacements', displacements)
    structure.new_array('forces', forces)

    structure.positions = atoms_ideal.get_positions()
    structure.calc = None

# save structures
if not os.path.isdir(os.path.dirname(structures_fname)):
    os.mkdir(os.path.dirname(structures_fname))
write(structures_fname, structures)

Source code

The complete source code is available in tutorial/basic/1_prepare_reference_data.py
'''
Prepare training structures for FCC-Ni using an EMT calculator and a
Monte Carlo rattle approach for generating displacements.

Runs in approximately 10 seconds on an Intel Core i5-4670K CPU.
'''

import os
from ase.io import write
from ase.build import bulk
from ase.calculators.emt import EMT
from hiphive.structure_generation import generate_mc_rattled_structures


# parameters
structures_fname = 'structures/rattled_structures.extxyz'
number_of_structures = 5
cell_size = 4
rattle_std = 0.03
minimum_distance = 2.3

# setup
atoms_ideal = bulk('Ni', cubic=True).repeat(cell_size)
calc = EMT()

# generate structures
structures = generate_mc_rattled_structures(
    atoms_ideal, number_of_structures, rattle_std, minimum_distance)
for structure in structures:
    structure.set_calculator(calc)
    forces = structure.get_forces()

    displacements = structure.positions - atoms_ideal.get_positions()
    structure.new_array('displacements', displacements)
    structure.new_array('forces', forces)

    structure.positions = atoms_ideal.get_positions()
    structure.calc = None

# save structures
if not os.path.isdir(os.path.dirname(structures_fname)):
    os.mkdir(os.path.dirname(structures_fname))
write(structures_fname, structures)