Crystal structure à la CRYSTAL

There are presently three different input structure declarations:

  • Molecule defines a molecule, e.g. a 0-d object.
  • Crystal defines a crystal, e.g. a 3-d object.
  • External wraps around a Structure instance. It allows mixing both declarative and transformative structural definitions.
class pylada.dftcrystal.molecule.Molecule(symmgroup=1, **kwargs)[source]

Bases: pylada.tools.input.listblock.ListBlock

Base class for functional crystal structures for CRYSTAL.

Usage is similar to Crystal. Please look there for more information.

add_atom(*args, **kwargs)[source]

Adds an atom to the structure.

append(keyword, raw=None)[source]

Appends an item.

Some shortcuts are accpted:

  • ‘breaksym’
  • ‘keepsymm’
  • ‘angstrom’
  • ‘bohr’
  • ‘fractional’
Returns:self, so calls can be chained.
atoms = None

List of atoms.

copy()[source]

Returns deep copy of self.

crystal_output[source]

CRYSTAL program output.

This is a string which contains the CRYSTAL output from a geometry run. Electronic calculations are not performed.

current_units[source]

Current units in transformation list.

This will one of “bohr”, “angstrom”, “fractional”, depending on the last encountered keyword in the list,

eval()[source]

Evaluates current structure.

Runs crystal to evaluate current structure.

Returns:a Structure instance.
extend()

L.extend(iterable) – extend list by appending elements from the iterable

extprt[source]

CRYSTAL external output.

This is a string which contains the structure in CRYSTAL‘s external output format. Mostly for debugging.

insert(i, keyword, raw=None)[source]

Inserts item at given position.

Some shortcuts are accpted:

  • ‘breaksym’
  • ‘keepsymm’
  • ‘angstrom’
  • ‘bohr’
  • ‘fractional’
is_angstrom[source]

True if current units are angstrom.

is_bohr[source]

True if current units are bohrs.

is_breaksym[source]

True if currently keeping symmetries.

is_fractional[source]

True if current units are fractional.

pop([index]) → item -- remove and return item at index (default last).

Raises IndexError if list is empty or index is out of range.

print_input(**kwargs)[source]

Returns CRYSTAL input.

remove()

L.remove(value) – remove first occurrence of value. Raises ValueError if the value is not present.

reverse()

L.reverse() – reverse IN PLACE

sort()

L.sort(cmp=None, key=None, reverse=False) – stable sort IN PLACE; cmp(x, y) -> -1, 0, 1

symmetry_operators[source]

Symmetry operators, as determined by CRYSTAL.

Runs crystal to evaluate the symmetry operators on the current structure.

symmgroup = None

Symmetry group.

class pylada.dftcrystal.crystal.Crystal(symmgroup=1, *args, **kwargs)[source]

Bases: pylada.dftcrystal.molecule.Molecule

CRYSTAL-wise structure, e.g. functional approach.

CRYSTAL proposes a functional approach to crystals, as opposed to the imperative style used by Pylada. In practice, this means that CRYSTAL declares a chain of functions which acts upon an initial data and transform it. The data is generally a space-group with a set of atomic sites. The functions can be affine transformations on these sites, additions and removals of sites, transformation upon the space-group, and even strain relaxation.

In practice, both approaches can “do the same thing”, and indeed both CRYSTAL and Pylada provide similar functionalities, e.g. creating a supercell from a unit-cell. However, there are clear benefits from allowing users to keep working the CRYSTAL way when working with CRYSTAL.

This class provides a python wrapper around CRYSTAL‘s approach. It is only a wrapper, in that it merely contains the data necessary to create a CRYSTAL input file. It does not re-implement any of CRYSTAL‘s algorithms. However, it does provides the ability to call CRYSTAL and extract the results as a Pylada Structure instance. In this way, both approaches can be mixed, allowing for a complete integration of CRYSTAL with python. At present, both the initial data and chain of functions are represented and stored within the same Crystal instance. This is a bit sub-optimal. A better implementation would make clear the separation bewteen initial data and functions. However, it is less wordy.

The initial data upon which CRYSTAL applies its chain of functions is defined using the symmgroup, args, and atoms. The first references the space-group of the crystal, the second defines the lattice parameters, and the last holds the (initial) atomic sites. Crystal is also a list where each item is an operation upon the initial crystal.

In practice, the initial data is declared as follows:

>>> from pylada.dftcrystal import Crystal
>>> crystal = Crystal(227, 5.43)                                        \
...                  .add_atom(0.125, 0.125, 0.125, "Si")

This declares the diamond silicon structure. The first argument is the space-group, and the second the only required lattice parameter. If other parameters were needed they would be listed directly Crystal(?, a, b, c, alpha, beta, gamma). Only the parameters required for that particular space-group should be listed.

The second line adds an atomic site to the initial structure. add_atom() returns an the Crystal instance itself, so that atomic site declarations can be chained:

>>> crystal = Crystal(...)                                              \
...           .add_atom(...)                                            \
...           .add_atom(...)                                            \
...           .add_atom(...)

Only those atoms which are strictly inequivalent by symmetry operations should be listed.

Crystal instances function as lists of transformations which are to be applied to the initial structure. The simplest way to add an operation is to use the traditional CRYSTAL format:

>>> crystal = Crystal(227, 5.43)                                        \
...                  .add_atom(0.125, 0.125, 0.125, "Si")               \
...                  .append('supercel', '2 0 0 0 1 0 0 0 1')

Here we have created a supercell of diamond with two unit cell in the (100) direction. The first string in append() is the keyword and the second string its input. Much as add_atom(), append() returns the calling instance of Crystal so that calls can be chained into a single declarative expression.

A number of operations are implemented in a more pythonic manner. These can be added to the chain of functions by calling append() with an operation instance as a the only argument.

>>> from pylada.dftcrystal import Slabcut
>>> crystal.append( Slabcut(hkl=(1, 0, 0), isup=1, nl=3) )

Slabcut is an operation to create a thin-film from a 3d bulk material.

Finally, the whole “data+functions” object can be evaluated with eval(). This will return a Structure instance which can be used with other Pylada functionalities. Internally, eval() makes a call to CRYSTAL and greps the output to construct the output structure.

Parameters:
  • symmgroup – String or integer denoting the space-group.
  • args – Lattice parameters \(a\), \(b\), \(c\), \(\alpha\), \(\beta\), \(\gamma\). In practice, these parameters are listed as given in the third (or fourth) line of the input to CRYSTAL. Hence it should conform to the same syntax and the same order.
  • shift – Optional. Non-standard shift of the origin. Should be a sequence of three floats.

See also

For operations, see geometry.

symmgroup

Index or name of the space-group. Either form need make sense to CRYSTAL.

params

List of crystal parameters. These are printed as are and in the same order directly to CRYSTAL‘s input.

atoms

List of atomic sites in the initial structure. The items should be of type Atom. The easiest approach is to add them using add_atom().

add_atom(*args, **kwargs)

Adds an atom to the structure.

append(keyword, raw=None)

Appends an item.

Some shortcuts are accpted:

  • ‘breaksym’
  • ‘keepsymm’
  • ‘angstrom’
  • ‘bohr’
  • ‘fractional’
Returns:self, so calls can be chained.
copy()

Returns deep copy of self.

crystal_output

CRYSTAL program output.

This is a string which contains the CRYSTAL output from a geometry run. Electronic calculations are not performed.

current_units

Current units in transformation list.

This will one of “bohr”, “angstrom”, “fractional”, depending on the last encountered keyword in the list,

eval()

Evaluates current structure.

Runs crystal to evaluate current structure.

Returns:a Structure instance.
extend()

L.extend(iterable) – extend list by appending elements from the iterable

extprt

CRYSTAL external output.

This is a string which contains the structure in CRYSTAL‘s external output format. Mostly for debugging.

insert(i, keyword, raw=None)

Inserts item at given position.

Some shortcuts are accpted:

  • ‘breaksym’
  • ‘keepsymm’
  • ‘angstrom’
  • ‘bohr’
  • ‘fractional’
is_angstrom

True if current units are angstrom.

is_bohr

True if current units are bohrs.

is_breaksym

True if currently keeping symmetries.

is_fractional

True if current units are fractional.

params = None

Lattice parameters.

pop([index]) → item -- remove and return item at index (default last).

Raises IndexError if list is empty or index is out of range.

print_input(**kwargs)

Returns CRYSTAL input.

remove()

L.remove(value) – remove first occurrence of value. Raises ValueError if the value is not present.

reverse()

L.reverse() – reverse IN PLACE

shift[source]

Non-standard shift of the origin.

sort()

L.sort(cmp=None, key=None, reverse=False) – stable sort IN PLACE; cmp(x, y) -> -1, 0, 1

symmetry_operators

Symmetry operators, as determined by CRYSTAL.

Runs crystal to evaluate the symmetry operators on the current structure.

class pylada.dftcrystal.external.External(*args, **kwargs)[source]

Bases: pylada.dftcrystal.molecule.Molecule

Functional CRYSTAL-wise structure, starting from Pylada structure.

Provides a mixture of CRYSTAL and Pylada-style structures. The starting structure is a Structure instance which is inputed into CRYSTAL via the EXTERNAL keyword. This instance also accepts functional modifications which will act upon the initial structure, much as Crystal instances.

There are two ways of initializing an instance. The first allows the same interface as Structure.

>>> from quantities import angstrom
>>> from pylada.dftcrystal import External
>>> external = External([[0, 0.5, 0.5],
...                      [0.5, 0, 0.5],
...                      [0.5, 0.5, 0], scale=5.45*angstrom)            \
...                    .add_atom(0,0,0, 'Si')                           \
...                    .add_atom(0.25, 0.25, 0.25, 'Si')

The second approach is to use a predefined Structure instance:

>>> from pylada.dftcrystal import External
>>> external = External(copy=diamond)

Where diamond in the snippet above is the instance in question. Note that it is deepcopied upon initialization. In both cases, the initial structure can be accessed as initial.

In both cases, CRYSTAL transformations can be added to modify the initial structure.

>>> external.append('bohr')
>>> external.append(DiplaceAtoms().add_atom(0.1, 0, 0, 1))

In the snippet above, the displacement is in the current units of the structure, as understood by CRYSTAL. E.g. in “bohr“‘s here. In other words, the transformations should reference the structure the way CRYSTAL understands it. It might be indicated to use eval().

Note

Pylada will attempt to discover the symmetries at run time. It is also possible to enter them explicitely by setting initial‘s spacegroup attribute to a list of 4x3 matrices.

add_atom(*args, **kwargs)

Adds an atom to the structure.

add_atoms(*args, **kwargs)[source]

Adds atom to initial structure.

append(keyword, raw=None)

Appends an item.

Some shortcuts are accpted:

  • ‘breaksym’
  • ‘keepsymm’
  • ‘angstrom’
  • ‘bohr’
  • ‘fractional’
Returns:self, so calls can be chained.
atoms[source]

Alias to the initial structure.

cell[source]

Cell-vectors of the initial instance.

copy()

Returns deep copy of self.

crystal_output

CRYSTAL program output.

This is a string which contains the CRYSTAL output from a geometry run. Electronic calculations are not performed.

current_units

Current units in transformation list.

This will one of “bohr”, “angstrom”, “fractional”, depending on the last encountered keyword in the list,

eval()

Evaluates current structure.

Runs crystal to evaluate current structure.

Returns:a Structure instance.
extend()

L.extend(iterable) – extend list by appending elements from the iterable

extprt

CRYSTAL external output.

This is a string which contains the structure in CRYSTAL‘s external output format. Mostly for debugging.

initial = None

Initial structure.

This is a Structure instance.

insert(i, keyword, raw=None)

Inserts item at given position.

Some shortcuts are accpted:

  • ‘breaksym’
  • ‘keepsymm’
  • ‘angstrom’
  • ‘bohr’
  • ‘fractional’
is_angstrom

True if current units are angstrom.

is_bohr

True if current units are bohrs.

is_breaksym

True if currently keeping symmetries.

is_fractional

True if current units are fractional.

pop([index]) → item -- remove and return item at index (default last).

Raises IndexError if list is empty or index is out of range.

print_input(**kwargs)

Returns CRYSTAL input.

remove()

L.remove(value) – remove first occurrence of value. Raises ValueError if the value is not present.

reverse()

L.reverse() – reverse IN PLACE

sort()

L.sort(cmp=None, key=None, reverse=False) – stable sort IN PLACE; cmp(x, y) -> -1, 0, 1

symmetry_operators

Symmetry operators, as determined by CRYSTAL.

Runs crystal to evaluate the symmetry operators on the current structure.

Previous topic

Computational and Hamiltonian parameters

This Page