Unit Cell class¶

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

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