Unit Cell class

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:

ORTHORHOMBIC = 0

Orthorhombic cell, with the three angles equals to 90°

TRICLINIC = 1

Triclinic cell, with any values for the angles.

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 ORTHOROMBIC 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 an 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 ORTHOROMBIC. 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);

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);

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 orthorombic 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));