Specify the concentration ranges of species

The first step in setting up CE in ASE is to specify the types of elements occupying each basis and their concentration ranges using Concentration class. For AuCu alloys, we consider the entire composition range of AuxCu1-x where \(0 \leq x \leq 1\). The Concentration object can be created simply as

>>> from clease.settings import Concentration
>>> conc = Concentration(basis_elements=[['Au', 'Cu']])

because there is no restriction imposed on the concentration range. Note that a nested list is passed for the basis_elements argument because the consituting elements are specified per basis and FCC (crystal structure of AuxCu_sub:1_-_x for all \(0 \leq x \leq 1\)) has only one basis. The initialization automatically creates a linear algebra representation of the default concentration range constraints. The equality condition of

\[A_\mathrm{eq} = \begin{bmatrix} \begin{bmatrix} 1 & 1 \end{bmatrix} \end{bmatrix}\]

and

\[b_\mathrm{eq} = \begin{bmatrix} 1 \end{bmatrix}\]

as well as the lower bound conditions of

\[A_\mathrm{lb} = \begin{bmatrix} \begin{bmatrix}1 & 0\end{bmatrix}, \begin{bmatrix}0 & 1\end{bmatrix} \end{bmatrix}\]

and

\[b_\mathrm{lb} = \begin{bmatrix}0 & 0\end{bmatrix}\]

are created automatically. The conditions represents the linear equations

\[A_\mathrm{eq} c_\mathrm{species} = b_\mathrm{eq}\]

and

\[A_\mathrm{lb} c_\mathrm{species} \geq b_\mathrm{lb},\]

where the concentration list, \(c_\mathrm{species}\), is defined as

\[c_\mathrm{species} = \begin{bmatrix} c_\mathrm{Au} & c_\mathrm{Cu} \end{bmatrix}.\]

The equality condition is then expressed as

\[c_\mathrm{Au} + c_\mathrm{Cu} = 1,\]

which specifies that elements Au and Cu constitute the entire basis (only one basis in this case). The lower bound conditions are expressed as

\[c_\mathrm{Au} \geq 0\]

and

\[c_\mathrm{Cu} \geq 0,\]

which speicifies that the concentrations of Au and Cu must be greater than or equal to zero.

The AuCu system presented in this tutorial does not impose any concentration constraints. However, we demonstrate how one can impose extra constraints by using an example case where the concentration of interest is AuxCu1_-_x where \(0 \leq x \leq 0.5\). The extra concentration constraint can be specified in one of three ways.

The first method is to specify the extra constraint using A_eq, b_eq, A_lb and b_lb. For this particular case, the extra constraint is specified using A_lb and b_lb arguments as

>>> from clease.settings import Concentration
>>> conc = Concentration(basis_elements=[['Au', 'Cu']], A_lb=[[2, 0]], b_lb=[1])

A list of many examples on how linear systems equations can be used, is found here.

The second method is to specify the concentration range using formula unit strings. The Concentration class contains set_conc_formula_unit() method which accepts formula strings and variable range, which can be invoked as

>>> from clease.settings import Concentration
>>> conc = Concentration(basis_elements=[['Au', 'Cu']])
>>> conc.set_conc_formula_unit(formulas=["Au<x>Cu<1-x>"], variable_range={"x": (0, 0.5)})

The last method is to specify the concentration range each constituting species using set_conc_ranges() method in Concentration class. The lower and upper bound of species are specified in a nested list in the same order as the basis_elements as

>>> from clease.settings import Concentration
>>> conc = Concentration(basis_elements=[['Au', 'Cu']])
>>> conc.set_conc_ranges(ranges=[[(0, 0.5), (0.5, 1)]])

The above three methods yields the same results where \(x\) is constrained to \(0 \leq x \leq 0.5\).

class clease.settings.concentration.Concentration(basis_elements=None, grouped_basis=None, A_lb=None, b_lb=None, A_eq=None, b_eq=None)[source]

Bases: object

Specify concentration ranges of consituting elements for cluster expansion. Concentration range can be specified in three different ways.

1. specifying the equality and lower bound conditions by specifying A_lb, b_lb, A_eq and b_eq during initialization, 2. using set_conc_formula_unit() method, and 3. using set_conc_ranges() method.

Parameters:

basis_elements: list

List of chemical symbols of elements to occupy each basis. Even for the cases where there is only one basis (e.g., fcc, bcc, sc), a list of symbols should be grouped by basis as in [[‘Cu’, ‘Au’]] (note the nested list form).

grouped_basis: list (optional, only used when basis are grouped)

Indices of basis_elements that are considered to be equivalent when specifying concentration (e.g., useful when two basis are shared by the same set of elements and no distinctions are made between them). As an example consider a structure with three sublattices A, B and C. If sublattice A and C should be occupied by the same elements and B is occupied by a different set of elements. We can group lattice A and C by passing [(0, 2), (1,)].

A_lb: list (optional, only used for linear algebra representation)

A two-dimention matrix (or nested list) used to specify the lower bounds of the concentration ranges.

b_lb: list (optional, only used for linear algebra representation)

A list used tp specify the lower bounds of the concentration ranges.

A_eq: list (optional, only used for linear algegra representation)

A two-dimention matrix (or nested list) used to specify the equality conditions of the concentration ranges.

b_eq: list (optional, only used for linear algegra representation)

A list used tp specify the equality condisitons of the concentration ranges.

Example I: Single sublattice

>>> conc = Concentration(basis_elements=[['Au', 'Cu']])

Example II: Two sublattices >>> conc = Concentration(basis_elements=[[‘Au’, ‘Cu’], [‘Au’, ‘Cu’, ‘X’]])

Example III: Three sublattices where the first and third are grouped >>> conc = Concentration(basis_elements=[[‘Au’, ‘Cu’], [‘Au’, ‘Cu’, ‘X’], [‘Au’, ‘Cu’]], … grouped_basis=[(0, 2), (1,)])

__init__(basis_elements=None, grouped_basis=None, A_lb=None, b_lb=None, A_eq=None, b_eq=None)[source]
todict() dict[source]

Return neescary information to store as JSON.

classmethod from_dict(data)[source]

Initialize data from dictionary.

is_valid_conc(conc)[source]

Check if the concentration is valid.

add_usr_defined_eq_constraints(A_eq, b_eq)[source]

Add user defined constraints.

The concentrations are restrictred by the equation A_eq*c = b_eq

Parameters:

A_eq: nested list of numpy array

NxM matrix where N is the number of equations and M is the overall number of concentrations

b_eq: list or numpy array

right hand side vector of the equation length N

add_usr_defined_ineq_constraints(A_lb, b_lb)[source]

Add the user defined constraints.

The concentrations are restrictred by the equation A_lb*c > b_lb

Parameters:

A_lb: nested list of numpy array

NxM matrix where N is the number of equations and M is the overall number of concentrations

b_lb: list or numpy array

right hand side vector of the equation length N

set_conc_ranges(ranges)[source]

Set concentration range based on lower and upper bounds of each element.

Parameters:

ranges: list

Nested list of tuples with the same shape as basis_elements. If basis_elements is [[“Li”, “Ru”, “X”], [“O”, “X”]], ranges coulde be [[(0, 1), (0.2, 0.5), (0, 1)], [(0, 0.8), (0, 0.2)]]

set_conc_formula_unit(formulas=None, variable_range=None)[source]

Set concentration based on formula unit strings.

Parameters:

formulas: list

List constaining formula strings (e.g., [“Li<x>Ru<1>X<2-x>”, “O<3-y>X<y>”], [‘Al<4-4x>Mg<3x>Si<x>’’]) 1. formula string should be provided per basis. 2. formula string can only have integer numbers. 3. only one dvariable is allowed per basis. 4. each variable should have at least one instance of ‘clean’ representation (e.g., <x>, <y>)

variable_range: dict

Range of each variable used in formulas. key is a string, and the value should be int or float e.g., {“x”: (0, 2), “y”: (0, 0.7)}, {‘x’: (0., 1.)}

get_individual_comp_range()[source]

Return the concentration range of each component.

get_random_concentration(nib=None, sampling_attempts=200) ndarray[source]

Generate a valid random concentration.

Parameters:

sampling_attempts: int

Maximum number of attempts allowed to retrieve integer concentrations for each element in the structure.

property trivial_bounds

Return trivial bounds (i.e. 0 <= x <= 1)

NOTE: One can give stricter bounds, but these

trivial bounds are always satisfied

get_conc_min_component(comp)[source]

Generate all end points of the composition domain.

get_conc_max_component(comp)[source]

Generate all end points of the composition domain.

to_float_conc(num_atoms_in_basis, int_conc)[source]

Convert integer number to float concentration.

Parameters:

num_atoms_in_basis: list of int

Number of sites in each basis (e.g., [27, 27], [64]).

int_conc: array of int

Concentration per basis in an integer format, which corresponds to the number of corresponding element in that basis.

conc_in_int(num_atoms_in_basis, conc) ndarray[source]

Convert concentration value to an integer that corresponds to the number of corresponding elements.

Parameters:

num_atoms_in_basis: list of int

Number of sites in each basis (e.g., [27, 27], [64]).

conc: array of float

Concentration per basis normalized to 1. (e.g., arrays returned by self.get_random_concentration,

self.get_conc_max_component etc.)

get_concentration_vector(index_by_basis, atoms)[source]

Get the concentration vector.

is_valid(index_by_basis, atoms)[source]

Check if the atoms object has a valid concentration.

Parameters:

index_by_basis: list

list where the indices of atoms is grouped by basis

atoms: Atoms object

wrappend_and_sorted atoms object

clease_objtype = 'concentration'
classmethod load(fd, **kwargs)

Method for loading class object from JSON

save(fd)

Method for writing class object to a JSON file.