UnitCell

class chemfiles::UnitCell

An UnitCell represent the box containing the atoms, and its periodicity

A unit cell is fully represented by three lengths (a, b, c); and three angles (alpha, beta, gamma). The angles are stored in degrees, and the lengths in Angstroms.

A cell also has a matricial representation, by projecting the three base vector into an orthonormal base. We choose to represent such matrix as an upper triangular matrix:

| a_x   b_x   c_x |
|  0    b_y   c_y |
|  0     0    c_z |

Public Types

enum CellShape

Possible shapes for the unit cell.

Values:

enumerator ORTHORHOMBIC = 0

Orthorhombic cell, with the three angles equals to 90°

enumerator TRICLINIC = 1

Triclinic cell, with any values for the angles.

enumerator INFINITE = 2

Infinite cell, to use when there is no cell.

Public Functions

UnitCell()

Construct an INFINITE unit cell, with all lengths set to 0

auto cell = UnitCell();

assert(cell.shape() == UnitCell::INFINITE);

assert(cell.a() == 0);
assert(cell.b() == 0);
assert(cell.c() == 0);

assert(cell.alpha() == 90);
assert(cell.beta() == 90);
assert(cell.gamma() == 90);

UnitCell(double a)

Construct a cubic unit cell of side size a

auto cell = UnitCell(32);

assert(cell.shape() == UnitCell::ORTHORHOMBIC);

assert(cell.a() == 32);
assert(cell.b() == 32);
assert(cell.c() == 32);

assert(cell.alpha() == 90);
assert(cell.beta() == 90);
assert(cell.gamma() == 90);

UnitCell(double a, double b, double c)

Construct an ORTHORHOMBIC unit cell of side size a, b, c

auto cell = UnitCell(11, 22, 33);

assert(cell.shape() == UnitCell::ORTHORHOMBIC);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

assert(cell.alpha() == 90);
assert(cell.beta() == 90);
assert(cell.gamma() == 90);

UnitCell(double a, double b, double c, double alpha, double beta, double gamma)

Construct a unit cell of side size a, b, c, and cell angles alpha, beta, gamma.

If all of alpha, beta and gamma are 90.0, then the cell is ORTHORHOMBIC. Else a TRICLINIC cell is created.

auto cell = UnitCell(11, 22, 33);

assert(cell.shape() == UnitCell::ORTHORHOMBIC);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

assert(cell.alpha() == 90);
assert(cell.beta() == 90);
assert(cell.gamma() == 90);

UnitCell(const Matrix3D &matrix)

Construct a unit cell via from an upper triangular matrix.

If a matrix of all zeros is given, then an infinite cell is created.

If only the diagonal of the matrix is non-zero, then the cell is ORTHORHOMBIC. Else a TRICLINIC cell is created.

auto cell = UnitCell(11, 22, 33);
auto matrix = cell.matrix();

assert(matrix[0][0] == 11);
assert(matrix[1][1] == 22);
assert(matrix[2][2] == 33);

assert(fabs(matrix[0][1]) < 1e-12);
assert(fabs(matrix[0][2]) < 1e-12);
assert(fabs(matrix[1][2]) < 1e-12);

assert(matrix[1][0] == 0);
assert(matrix[2][0] == 0);
assert(matrix[2][1] == 0);

auto cell2 = UnitCell(matrix);

assert(cell2.a() == 11);
assert(cell2.b() == 22);
assert(cell2.c() == 33);

assert(cell2.alpha() == 90);
assert(cell2.beta()  == 90);
assert(cell2.gamma() == 90);

Matrix3D matrix() const

Get the cell matrix, defined as the upper triangular matrix

| a_x   b_x   c_x |
|  0    b_y   c_y |
|  0     0    c_z |

auto cell = UnitCell(11, 22, 33);
auto matrix = cell.matrix();

assert(matrix[0][0] == 11);
assert(matrix[1][1] == 22);
assert(matrix[2][2] == 33);

assert(fabs(matrix[0][1]) < 1e-12);
assert(fabs(matrix[0][2]) < 1e-12);
assert(fabs(matrix[1][2]) < 1e-12);

assert(matrix[1][0] == 0);
assert(matrix[2][0] == 0);
assert(matrix[2][1] == 0);

auto cell2 = UnitCell(matrix);

assert(cell2.a() == 11);
assert(cell2.b() == 22);
assert(cell2.c() == 33);

assert(cell2.alpha() == 90);
assert(cell2.beta()  == 90);
assert(cell2.gamma() == 90);

CellShape shape() const

Get the cell shape

auto cell = UnitCell(11, 22, 33);
assert(cell.shape() == UnitCell::ORTHORHOMBIC);

cell.set_shape(UnitCell::TRICLINIC);
assert(cell.shape() == UnitCell::TRICLINIC);

void set_shape(CellShape shape)

Set the cell shape to shape

auto cell = UnitCell(11, 22, 33);
assert(cell.shape() == UnitCell::ORTHORHOMBIC);

cell.set_shape(UnitCell::TRICLINIC);
assert(cell.shape() == UnitCell::TRICLINIC);

Exceptions
  • Error: if shape is ORTHORHOMBIC and some angles are not 90°, or if shape is INFINITE and some lengths are not 0.0.

double a() const

Get the first lenght (a) of the cell

auto cell = UnitCell(11, 22, 33);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

cell.set_a(111);
cell.set_b(222);
cell.set_c(333);

assert(cell.a() == 111);
assert(cell.b() == 222);
assert(cell.c() == 333);

void set_a(double val)

Set the first lenght (a) of the cell

auto cell = UnitCell(11, 22, 33);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

cell.set_a(111);
cell.set_b(222);
cell.set_c(333);

assert(cell.a() == 111);
assert(cell.b() == 222);
assert(cell.c() == 333);

Exceptions
  • Error: if the cell shape is INFINITE.

double b() const

Get the second lenght (b) of the cell

auto cell = UnitCell(11, 22, 33);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

cell.set_a(111);
cell.set_b(222);
cell.set_c(333);

assert(cell.a() == 111);
assert(cell.b() == 222);
assert(cell.c() == 333);

void set_b(double val)

Set the second lenght (b) of the cell

auto cell = UnitCell(11, 22, 33);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

cell.set_a(111);
cell.set_b(222);
cell.set_c(333);

assert(cell.a() == 111);
assert(cell.b() == 222);
assert(cell.c() == 333);

Exceptions
  • Error: if the cell shape is INFINITE.

double c() const

Get the third lenght (c) of the cell

auto cell = UnitCell(11, 22, 33);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

cell.set_a(111);
cell.set_b(222);
cell.set_c(333);

assert(cell.a() == 111);
assert(cell.b() == 222);
assert(cell.c() == 333);

void set_c(double val)

Set the third lenght (c) of the cell

auto cell = UnitCell(11, 22, 33);

assert(cell.a() == 11);
assert(cell.b() == 22);
assert(cell.c() == 33);

cell.set_a(111);
cell.set_b(222);
cell.set_c(333);

assert(cell.a() == 111);
assert(cell.b() == 222);
assert(cell.c() == 333);

Exceptions
  • Error: if the cell shape is INFINITE.

double alpha() const

Get the first angle (alpha) of the cell

auto cell = UnitCell(1, 1, 1, 60, 80, 123);

assert(cell.alpha() == 60);
assert(cell.beta() == 80);
assert(cell.gamma() == 123);

cell.set_alpha(91);
cell.set_beta(92);
cell.set_gamma(93);

assert(cell.alpha() == 91);
assert(cell.beta() == 92);
assert(cell.gamma() == 93);

void set_alpha(double val)

Set the first angle (alpha) of the cell

auto cell = UnitCell(1, 1, 1, 60, 80, 123);

assert(cell.alpha() == 60);
assert(cell.beta() == 80);
assert(cell.gamma() == 123);

cell.set_alpha(91);
cell.set_beta(92);
cell.set_gamma(93);

assert(cell.alpha() == 91);
assert(cell.beta() == 92);
assert(cell.gamma() == 93);

Exceptions
  • Error: if the cell shape is not TRICLINIC.

double beta() const

Get the second angle (beta) of the cell

auto cell = UnitCell(1, 1, 1, 60, 80, 123);

assert(cell.alpha() == 60);
assert(cell.beta() == 80);
assert(cell.gamma() == 123);

cell.set_alpha(91);
cell.set_beta(92);
cell.set_gamma(93);

assert(cell.alpha() == 91);
assert(cell.beta() == 92);
assert(cell.gamma() == 93);

void set_beta(double val)

Set the second angle (beta) of the cell if possible

auto cell = UnitCell(1, 1, 1, 60, 80, 123);

assert(cell.alpha() == 60);
assert(cell.beta() == 80);
assert(cell.gamma() == 123);

cell.set_alpha(91);
cell.set_beta(92);
cell.set_gamma(93);

assert(cell.alpha() == 91);
assert(cell.beta() == 92);
assert(cell.gamma() == 93);

Exceptions
  • Error: if the cell shape is not TRICLINIC.

double gamma() const

Get the third angle (gamma) of the cell

auto cell = UnitCell(1, 1, 1, 60, 80, 123);

assert(cell.alpha() == 60);
assert(cell.beta() == 80);
assert(cell.gamma() == 123);

cell.set_alpha(91);
cell.set_beta(92);
cell.set_gamma(93);

assert(cell.alpha() == 91);
assert(cell.beta() == 92);
assert(cell.gamma() == 93);

void set_gamma(double val)

Set the third angle (gamma) of the cell if possible

auto cell = UnitCell(1, 1, 1, 60, 80, 123);

assert(cell.alpha() == 60);
assert(cell.beta() == 80);
assert(cell.gamma() == 123);

cell.set_alpha(91);
cell.set_beta(92);
cell.set_gamma(93);

assert(cell.alpha() == 91);
assert(cell.beta() == 92);
assert(cell.gamma() == 93);

Exceptions
  • Error: if the cell shape is not TRICLINIC.

double volume() const

Get the unit cell volume

auto cell = UnitCell(11, 22, 33);
assert(cell.volume() == 11 * 22 * 33);

Vector3D wrap(const Vector3D &vector) const

Wrap the vector in the unit cell, using periodic boundary conditions.

For an orthorhombic unit cell, this make sure that all the vector components are between -L/2 and L/2 where L is the corresponding cell length.

auto cell = UnitCell(11, 22, 33);
assert(cell.wrap(Vector3D(14, -12, 5)) == Vector3D(3, 10, 5));