EvolutionarySQS

class EvolutionarySQS(alloy, cluster_max_diameters, repetitions=(1, 1, 1), seed_configuration=None, number_of_generations=40, population_size=20, number_to_promote=2, heredity_probability=0.5, permutation_probability=0.5, n_best=10, rng=None)

Generate a special quasi-random structure (SQS) using genetic optimization.

Parameters:
  • alloy (AlloyConfiguration) – An alloy configuration.
  • cluster_max_diameters (dict) – A dictionary that maps the cluster order to the maximum diameter for clusters of that order. They keys should be integers greater than equal to two and the values are positive PhysicalQuantities with units of distance (typically at least as large as the nearest neighbor distance).
  • repetitions (list of type int) – The number of times to repeat the alloy configuration.
    Default: (1, 1, 1)
  • seed_configuration (BulkConfiguration) – An initial guess of the SQS structure.
  • number_of_generations (int) – The number of times the population should be evolved.
  • population_size (int) – The number of individuals which are part of a population. The population size must be at least 5, but it is recommeded to use a large population size (>= 20) to obtain higher quality results.
  • number_to_promote (int) – The number of most fittest individuals to promote to the next generation.
    Default: 2
  • heredity_probability (float) – The unnormalized probabilty of using the heredity operator.
    Default: 0.5
  • permutation_probability (float) – The unnormalized probabilty of using the permutation operator. The permutation operator will only be used when there is more than one type of an element in the system.
    Default: 0.5
  • n_best (int) – The n best structures the correlation functions of which are closest to the truely random one.
  • rng (numpy.random.RandomState) – The random number generated used to generate the random number stream.
    Default: A new random number generator (seeded from OS entropy pool)
alloyConfiguration()
Returns:The alloy configuration. This is the same as the alloy configuration that was initially passed in.
Return type:AlloyConfiguration
bestStructure()
Returns:The SQS structure that best matches the random correlation function.
Return type:BulkConfiguration
bestStructures()
Returns:A list of the configurations sorted in order of increasing error.
Return type:list of type BulkConfiguration
evolvePopulation(number_of_generations)

Evolves the current population for number_of_generations generations.

Parameters:number_of_generations (int) – The number of times the genetic algorithm is applied to the population.
fitnesses()

Return the fitnesses of the current population. Sorted by descending fitness.

Returns:a list of fitnesses
Return type:list
objectiveFunction(configuration)

Evaluate the objective function for a configuration.

Parameters:configuration (BulkConfiguration) – The configuration to evaluate.
Returns:The SQS objective function.
Return type:float
population()

Return the current population.

Returns:a population
Return type:list of individuals
symmetries()

Return the international symbol for each individual of the current population. Sorted by descending fitness.

Returns:a list of international symbols
Return type:list of str

Usage Examples

Set up an evolutionary SQS optimization for a 64 atom SiGe alloy.

# Set up lattice
vector_a = [5.4306, 0.0, 0.0]*Angstrom
vector_b = [0.0, 5.4306, 0.0]*Angstrom
vector_c = [0.0, 0.0, 21.7224]*Angstrom
lattice = UnitCell(vector_a, vector_b, vector_c)

# Define site types
site_a = AlloySite(Germanium=0.5, Silicon=0.5)

# Define sites
sites = [
    site_a, site_a, site_a, site_a, site_a, site_a, site_a, site_a,
    site_a, site_a, site_a, site_a, site_a, site_a, site_a, site_a,
    site_a, site_a, site_a, site_a, site_a, site_a, site_a, site_a,
    site_a, site_a, site_a, site_a, site_a, site_a, site_a, site_a,
]

# Define coordinates
cartesian_coordinates = [[  0.     ,   0.     ,   0.     ],
                         [  0.     ,   0.     ,   5.4306 ],
                         [  0.     ,   0.     ,  10.8612 ],
                         [  0.     ,   0.     ,  16.2918 ],
                         [  1.35765,   1.35765,   1.35765],
                         [  1.35765,   1.35765,   6.78825],
                         [  1.35765,   1.35765,  12.21885],
                         [  1.35765,   1.35765,  17.64945],
                         [  2.7153 ,   2.7153 ,   0.     ],
                         [  2.7153 ,   2.7153 ,   5.4306 ],
                         [  2.7153 ,   2.7153 ,  10.8612 ],
                         [  2.7153 ,   2.7153 ,  16.2918 ],
                         [  4.07295,   4.07295,   1.35765],
                         [  4.07295,   4.07295,   6.78825],
                         [  4.07295,   4.07295,  12.21885],
                         [  4.07295,   4.07295,  17.64945],
                         [  2.7153 ,   0.     ,   2.7153 ],
                         [  2.7153 ,   0.     ,   8.1459 ],
                         [  2.7153 ,   0.     ,  13.5765 ],
                         [  2.7153 ,   0.     ,  19.0071 ],
                         [  4.07295,   1.35765,   4.07295],
                         [  4.07295,   1.35765,   9.50355],
                         [  4.07295,   1.35765,  14.93415],
                         [  4.07295,   1.35765,  20.36475],
                         [  0.     ,   2.7153 ,   2.7153 ],
                         [  0.     ,   2.7153 ,   8.1459 ],
                         [  0.     ,   2.7153 ,  13.5765 ],
                         [  0.     ,   2.7153 ,  19.0071 ],
                         [  1.35765,   4.07295,   4.07295],
                         [  1.35765,   4.07295,   9.50355],
                         [  1.35765,   4.07295,  14.93415],
                         [  1.35765,   4.07295,  20.36475]]*Angstrom


# Define the maximum diameter of each cluster.
cluster_max_diameters = {
    2: 4.9*Angstrom,
    3: 4.4*Angstrom,
    4: 2.5*Angstrom,
}

# Perform the SQS optimization.
sqs = EvolutionarySQS(
    alloy_configuration,
    cluster_max_diameters,
    number_of_generations=200,
    population_size=100,
    number_to_promote=10,
    heredity_probability=0.5,
    permutation_probability=0.5,
)

# Extract and save the best SQS structure after the optimization
best_sqs_configuration = sqs.bestStructure()
nlsave('sqs_sige_optimized.hdf5', best_sqs_configuration)

sige_evolutionary_sqs.py

Notes

EvolutionarySQS can be used to generate an optimized random alloy, based on the special quasi-random structure (SQS) method [vdWTdJ+13].

The desired composition and structure of an alloy can be set up via the AlloySite and AlloyConfiguration classes, which are used as input to EvolutionarySQS.

QuantumATK uses a genetic algorithm (similar to CrystalStructurePrediction) to permute the positions of the atoms in order to obtain correlation functions that match the correlation functions of an ideal random alloy configuration. After the optimization, the bulk configuration with the best correlation functions can be extracted via the bestStructure() method. This configuration can then be used in further calculations.

[vdWTdJ+13]A. van de Walle, P. Tiwary, M. de Jong, D.L. Olmsted, M. Asta, A. Dick, D. Shin, Y. Wang, L.-Q. Chen, and Z.-K. Liu. Efficient stochastic generation of special quasirandom structures. Calphad, 42:13 – 18, 2013. URL: http://www.sciencedirect.com/science/article/pii/S0364591613000540.