@mat3ra/made 2024.3.22-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +10 -0
- package/.eslintrc.json +11 -0
- package/.mocharc.json +5 -0
- package/.prettierignore +1 -0
- package/.prettierrc +6 -0
- package/LICENSE.md +15 -0
- package/README.md +167 -0
- package/dist/abstract/array_with_ids.d.ts +43 -0
- package/dist/abstract/array_with_ids.js +88 -0
- package/dist/abstract/scalar_with_id.d.ts +25 -0
- package/dist/abstract/scalar_with_id.js +44 -0
- package/dist/basis/basis.d.ts +269 -0
- package/dist/basis/basis.js +499 -0
- package/dist/basis/constrained_basis.d.ts +56 -0
- package/dist/basis/constrained_basis.js +90 -0
- package/dist/basis/types.d.ts +1 -0
- package/dist/basis/types.js +2 -0
- package/dist/cell/cell.d.ts +45 -0
- package/dist/cell/cell.js +88 -0
- package/dist/cell/conventional_cell.d.ts +22 -0
- package/dist/cell/conventional_cell.js +83 -0
- package/dist/cell/primitive_cell.d.ts +9 -0
- package/dist/cell/primitive_cell.js +166 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +25 -0
- package/dist/constraints/constraints.d.ts +45 -0
- package/dist/constraints/constraints.js +49 -0
- package/dist/lattice/lattice.d.ts +104 -0
- package/dist/lattice/lattice.js +208 -0
- package/dist/lattice/lattice_bravais.d.ts +59 -0
- package/dist/lattice/lattice_bravais.js +120 -0
- package/dist/lattice/lattice_vectors.d.ts +46 -0
- package/dist/lattice/lattice_vectors.js +98 -0
- package/dist/lattice/reciprocal/lattice_reciprocal.d.ts +75 -0
- package/dist/lattice/reciprocal/lattice_reciprocal.js +148 -0
- package/dist/lattice/reciprocal/paths.d.ts +24 -0
- package/dist/lattice/reciprocal/paths.js +136 -0
- package/dist/lattice/reciprocal/symmetry_points.d.ts +8 -0
- package/dist/lattice/reciprocal/symmetry_points.js +866 -0
- package/dist/lattice/types.d.ts +49 -0
- package/dist/lattice/types.js +127 -0
- package/dist/lattice/unit_cell.d.ts +30 -0
- package/dist/lattice/unit_cell.js +31 -0
- package/dist/made.d.ts +40 -0
- package/dist/made.js +39 -0
- package/dist/material.d.ts +1562 -0
- package/dist/material.js +317 -0
- package/dist/math.d.ts +395 -0
- package/dist/math.js +7 -0
- package/dist/parsers/cif.d.ts +10 -0
- package/dist/parsers/cif.js +21 -0
- package/dist/parsers/errors.d.ts +5 -0
- package/dist/parsers/errors.js +11 -0
- package/dist/parsers/espresso.d.ts +10 -0
- package/dist/parsers/espresso.js +24 -0
- package/dist/parsers/native_format_parsers.d.ts +26 -0
- package/dist/parsers/native_format_parsers.js +52 -0
- package/dist/parsers/parsers.d.ts +13 -0
- package/dist/parsers/parsers.js +17 -0
- package/dist/parsers/poscar.d.ts +31 -0
- package/dist/parsers/poscar.js +180 -0
- package/dist/parsers/xyz.d.ts +62 -0
- package/dist/parsers/xyz.js +167 -0
- package/dist/parsers/xyz_combinatorial_basis.d.ts +64 -0
- package/dist/parsers/xyz_combinatorial_basis.js +241 -0
- package/dist/tools/basis.d.ts +22 -0
- package/dist/tools/basis.js +100 -0
- package/dist/tools/cell.d.ts +9 -0
- package/dist/tools/cell.js +39 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +15 -0
- package/dist/tools/material.d.ts +25 -0
- package/dist/tools/material.js +54 -0
- package/dist/tools/supercell.d.ts +22 -0
- package/dist/tools/supercell.js +62 -0
- package/dist/tools/surface.d.ts +10 -0
- package/dist/tools/surface.js +147 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +2 -0
- package/package.json +89 -0
- package/pyproject.toml +77 -0
- package/src/js/abstract/array_with_ids.ts +100 -0
- package/src/js/abstract/scalar_with_id.ts +53 -0
- package/src/js/basis/basis.ts +607 -0
- package/src/js/basis/constrained_basis.ts +107 -0
- package/src/js/basis/types.ts +1 -0
- package/src/js/cell/cell.ts +109 -0
- package/src/js/cell/conventional_cell.ts +89 -0
- package/src/js/cell/primitive_cell.ts +189 -0
- package/src/js/constants.js +4 -0
- package/src/js/constraints/constraints.ts +63 -0
- package/src/js/lattice/lattice.ts +229 -0
- package/src/js/lattice/lattice_bravais.ts +170 -0
- package/src/js/lattice/lattice_vectors.ts +126 -0
- package/src/js/lattice/reciprocal/lattice_reciprocal.js +155 -0
- package/src/js/lattice/reciprocal/paths.js +134 -0
- package/src/js/lattice/reciprocal/symmetry_points.ts +886 -0
- package/src/js/lattice/types.ts +142 -0
- package/src/js/lattice/unit_cell.ts +66 -0
- package/src/js/made.js +36 -0
- package/src/js/material.ts +398 -0
- package/src/js/math.js +6 -0
- package/src/js/parsers/cif.js +22 -0
- package/src/js/parsers/errors.js +7 -0
- package/src/js/parsers/espresso.ts +30 -0
- package/src/js/parsers/native_format_parsers.js +51 -0
- package/src/js/parsers/parsers.js +13 -0
- package/src/js/parsers/poscar.ts +201 -0
- package/src/js/parsers/xyz.ts +216 -0
- package/src/js/parsers/xyz_combinatorial_basis.js +243 -0
- package/src/js/tools/basis.js +116 -0
- package/src/js/tools/cell.js +36 -0
- package/src/js/tools/index.js +11 -0
- package/src/js/tools/material.js +60 -0
- package/src/js/tools/supercell.ts +80 -0
- package/src/js/tools/surface.js +176 -0
- package/src/js/types.ts +4 -0
- package/src/py/__init__.py +0 -0
- package/src/py/mat3ra/__init__.py +0 -0
- package/src/py/mat3ra/made/__init__.py +5 -0
- package/tests/.gitattributes +1 -0
- package/tests/fixtures/AsGe-basis.json +3 -0
- package/tests/fixtures/C2H4-translated.json +3 -0
- package/tests/fixtures/C2H4.json +3 -0
- package/tests/fixtures/FeLiSi-basis.json +3 -0
- package/tests/fixtures/FeO.json +3 -0
- package/tests/fixtures/Ge2-basis.json +3 -0
- package/tests/fixtures/Graphene.json +3 -0
- package/tests/fixtures/Graphene.poscar +3 -0
- package/tests/fixtures/H2+H-final.json +3 -0
- package/tests/fixtures/H2+H-image.json +3 -0
- package/tests/fixtures/H2+H-initial.json +3 -0
- package/tests/fixtures/H2O.poscar +3 -0
- package/tests/fixtures/LiFeSi-basis.json +3 -0
- package/tests/fixtures/Na.json +3 -0
- package/tests/fixtures/Na4Cl4-cartesian.json +3 -0
- package/tests/fixtures/Na4Cl4.json +3 -0
- package/tests/fixtures/Na4Cl4.poscar +3 -0
- package/tests/fixtures/Ni-hex.json +3 -0
- package/tests/fixtures/Ni-hex.poscar +3 -0
- package/tests/fixtures/OSi-basis.json +3 -0
- package/tests/fixtures/Si-hex.json +3 -0
- package/tests/fixtures/Si-hex.poscar +3 -0
- package/tests/fixtures/Si-pwscf.in +3 -0
- package/tests/fixtures/Si-slab.json +3 -0
- package/tests/fixtures/Si-supercell.json +3 -0
- package/tests/fixtures/Si.json +3 -0
- package/tests/fixtures/Si2-basis-repeated.json +3 -0
- package/tests/fixtures/Si2-basis.json +3 -0
- package/tests/fixtures/Zr1H23Zr1H1.json +3 -0
- package/tests/fixtures/Zr1H23Zr1H1.poscar +3 -0
- package/tests/fixtures/atomic-constraints.json +3 -0
- package/tests/js/basis/basis.js +221 -0
- package/tests/js/cell/cell.js +21 -0
- package/tests/js/cell/primitive_cell.js +17 -0
- package/tests/js/constraints/constraints.js +27 -0
- package/tests/js/enums.js +40 -0
- package/tests/js/lattice/lattice.js +31 -0
- package/tests/js/lattice/lattice_bravais.js +17 -0
- package/tests/js/lattice/lattice_reciprocal.js +99 -0
- package/tests/js/lattice/lattice_vectors.js +10 -0
- package/tests/js/material.test.js +11 -0
- package/tests/js/parsers/espresso.js +12 -0
- package/tests/js/parsers/native_formats.js +30 -0
- package/tests/js/parsers/poscar.js +21 -0
- package/tests/js/parsers/xyz.js +25 -0
- package/tests/js/parsers/xyz_combinatorial_basis.js +153 -0
- package/tests/js/setup.js +6 -0
- package/tests/js/tools/basis.js +18 -0
- package/tests/js/tools/supercell.js +23 -0
- package/tests/js/tools/surface.js +12 -0
- package/tests/js/utils.js +17 -0
- package/tests/py/__init__.py +0 -0
- package/tests/py/unit/__init__.py +0 -0
- package/tests/py/unit/test_sample.py +10 -0
- package/tsconfig.json +3 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { LatticeBravais } from "../lattice/lattice_bravais";
|
|
2
|
+
import math from "../math";
|
|
3
|
+
import SupercellTools from "./supercell";
|
|
4
|
+
|
|
5
|
+
const MULT = math.multiply;
|
|
6
|
+
const ADD = math.add;
|
|
7
|
+
const DOT = math.product;
|
|
8
|
+
const getMatrixInLeftHandedRepresentation = (matrix) => {
|
|
9
|
+
return math.det(matrix) < 0 ? MULT(matrix, -1) : matrix;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Helper function for extended GCD.
|
|
14
|
+
* Inspired by https://gitlab.com/ase/ase/blob/master/ase/build/general_surface.py
|
|
15
|
+
* @param {Number} a
|
|
16
|
+
* @param {Number} b
|
|
17
|
+
* @return {Array}
|
|
18
|
+
*/
|
|
19
|
+
function extGCD(a, b) {
|
|
20
|
+
if (b === 0) return [1, 0];
|
|
21
|
+
if (math.mod(a, b) === 0) return [0, 1];
|
|
22
|
+
|
|
23
|
+
const [x, y] = extGCD(b, math.mod(a, b));
|
|
24
|
+
return [y, x - y * math.floor(a, b)];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generates a slab scaling matrix for the specified cell based on miller indices.
|
|
29
|
+
* Inspired by from https://gitlab.com/ase/ase/blob/master/ase/build/general_surface.py.
|
|
30
|
+
* @param cell {Cell}
|
|
31
|
+
* @param millerIndices {Number[]}
|
|
32
|
+
* @param tol {Number} Zero-value tolerance
|
|
33
|
+
* @return {Number[][]}
|
|
34
|
+
*/
|
|
35
|
+
function getMillerScalingMatrix(cell, millerIndices, tol = 1e-8) {
|
|
36
|
+
if (!millerIndices.reduce((a, b) => math.abs(a) + math.abs(b)))
|
|
37
|
+
throw new Error("Miller indices are zeros.");
|
|
38
|
+
|
|
39
|
+
let scalingMatrix;
|
|
40
|
+
|
|
41
|
+
const [h, k, l] = millerIndices;
|
|
42
|
+
const [h0, k0, l0] = millerIndices.map((i) => i === 0);
|
|
43
|
+
|
|
44
|
+
if ((h0 && k0) || (h0 && l0) || (k0 && l0)) {
|
|
45
|
+
// if any two indices are zero
|
|
46
|
+
|
|
47
|
+
if (!h0) {
|
|
48
|
+
scalingMatrix = [
|
|
49
|
+
[0, 1, 0],
|
|
50
|
+
[0, 0, 1],
|
|
51
|
+
[1, 0, 0],
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
if (!k0) {
|
|
55
|
+
scalingMatrix = [
|
|
56
|
+
[0, 0, 1],
|
|
57
|
+
[1, 0, 0],
|
|
58
|
+
[0, 1, 0],
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
if (!l0) {
|
|
62
|
+
scalingMatrix = [
|
|
63
|
+
[1, 0, 0],
|
|
64
|
+
[0, 1, 0],
|
|
65
|
+
[0, 0, 1],
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
const [a1, a2, a3] = cell.vectorsAsArray;
|
|
70
|
+
// z1 = (k * a1 - h * a2)
|
|
71
|
+
// z2 = (l * a1 - h * a3)
|
|
72
|
+
// z3 = l * a2 - k * a3)
|
|
73
|
+
const z1 = ADD(MULT(k, a1), MULT(-1, h, a2));
|
|
74
|
+
const z2 = ADD(MULT(l, a1), MULT(-1, h, a3));
|
|
75
|
+
const z3 = ADD(MULT(l, a2), MULT(-1, k, a3));
|
|
76
|
+
|
|
77
|
+
let [p, q] = extGCD(k, l);
|
|
78
|
+
|
|
79
|
+
const k1 = DOT(ADD(MULT(p, z1), MULT(q, z2)), z3);
|
|
80
|
+
const k2 = DOT(ADD(MULT(l, z1), MULT(-1, k, z2)), z3);
|
|
81
|
+
|
|
82
|
+
if (math.abs(k2) > tol) {
|
|
83
|
+
const i = -parseInt(math.round(k1 / k2), 10);
|
|
84
|
+
[p, q] = [p + i * l, q - i * k];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const [a, b] = extGCD(p * k + q * l, h);
|
|
88
|
+
const c1 = [p * k + q * l, -p * h, -q * h];
|
|
89
|
+
const c2 = [0, l, -k].map((c) => math.trunc(c / math.gcd(l, k))); // floor division
|
|
90
|
+
const c3 = [b, a * p, a * q];
|
|
91
|
+
|
|
92
|
+
scalingMatrix = [c1, c2, c3];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return getMatrixInLeftHandedRepresentation(scalingMatrix);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Scale the surface cell in out-of-plane direction according to thickness
|
|
100
|
+
* and construct the lateral supercell from vx/vy parameters.
|
|
101
|
+
* @param bulkCell {Cell}
|
|
102
|
+
* @param surfaceCell {Cell}
|
|
103
|
+
* @param outOfPlaneAxisIndex {Number} Index of the cell vector most collinear with the out-of-surface-plane vector
|
|
104
|
+
* @param thickness {Number} Surface (Slab) thickness in layers (Positive Integer).
|
|
105
|
+
* @param vx {Number} Size of lateral supercell along the direction of the first (x) cell vector (Positive Integer).
|
|
106
|
+
* @param vy {Number} Size of lateral supercell along the direction of the second (y) cell vector (Positive Integer).
|
|
107
|
+
* @return {Number[][]}
|
|
108
|
+
*/
|
|
109
|
+
function getDimensionsScalingMatrix(bulkCell, surfaceCell, outOfPlaneAxisIndex, thickness, vx, vy) {
|
|
110
|
+
const transformationMatrix = math.eye(3).toArray();
|
|
111
|
+
const vxIndex = outOfPlaneAxisIndex === 2 ? 0 : outOfPlaneAxisIndex + 1;
|
|
112
|
+
const vyIndex = vxIndex === 2 ? 0 : vxIndex + 1;
|
|
113
|
+
|
|
114
|
+
transformationMatrix[outOfPlaneAxisIndex] = MULT(
|
|
115
|
+
thickness,
|
|
116
|
+
transformationMatrix[outOfPlaneAxisIndex],
|
|
117
|
+
);
|
|
118
|
+
transformationMatrix[vxIndex] = MULT(vx, transformationMatrix[vxIndex]);
|
|
119
|
+
transformationMatrix[vyIndex] = MULT(vy, transformationMatrix[vyIndex]);
|
|
120
|
+
|
|
121
|
+
return transformationMatrix;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/*
|
|
125
|
+
* Generate a config object for a surface based on a set of parameters.
|
|
126
|
+
* @param material {Material} The parent material (bulk) this surface is constructed from
|
|
127
|
+
* @param millerIndices {Number[]} Miller Indices that define the surface cleavage.
|
|
128
|
+
* @param numberOfLayers {Number} Surface (Slab) thickness in layers (Positive Integer).
|
|
129
|
+
* @param vx {Number} Size of lateral supercell along the direction of the first (x) cell vector (Positive Integer).
|
|
130
|
+
* @param vy {Number} Size of lateral supercell along the direction of the second (y) cell vector (Positive Integer).
|
|
131
|
+
* @return {Object}
|
|
132
|
+
*/
|
|
133
|
+
function generateConfig(material, millerIndices, numberOfLayers = 1, vx = 1, vy = 1) {
|
|
134
|
+
if (numberOfLayers < 1)
|
|
135
|
+
throw new Error("Made.tools.surface.generateConfig: number of layers < 1.");
|
|
136
|
+
|
|
137
|
+
const cell = material.Lattice.Cell;
|
|
138
|
+
const millerScalingMatrix = getMillerScalingMatrix(cell, millerIndices);
|
|
139
|
+
const millerSupercell = cell.cloneAndScaleByMatrix(millerScalingMatrix);
|
|
140
|
+
const millerPlanePseudoNormal = cell.convertPointToCartesian(millerIndices);
|
|
141
|
+
const outOfPlaneAxisIndex =
|
|
142
|
+
millerSupercell.getMostCollinearVectorIndex(millerPlanePseudoNormal);
|
|
143
|
+
const dimensionsScalingMatrix = getDimensionsScalingMatrix(
|
|
144
|
+
cell,
|
|
145
|
+
millerSupercell,
|
|
146
|
+
outOfPlaneAxisIndex,
|
|
147
|
+
numberOfLayers,
|
|
148
|
+
vx,
|
|
149
|
+
vy,
|
|
150
|
+
);
|
|
151
|
+
const supercellMatrix = MULT(dimensionsScalingMatrix, millerScalingMatrix);
|
|
152
|
+
const supercell = millerSupercell.cloneAndScaleByMatrix(dimensionsScalingMatrix);
|
|
153
|
+
const newBasis = SupercellTools.generateNewBasisWithinSupercell(
|
|
154
|
+
material.Basis,
|
|
155
|
+
cell,
|
|
156
|
+
supercell,
|
|
157
|
+
supercellMatrix,
|
|
158
|
+
);
|
|
159
|
+
const newLattice = LatticeBravais.fromVectors({
|
|
160
|
+
a: supercell.vector1,
|
|
161
|
+
b: supercell.vector2,
|
|
162
|
+
c: supercell.vector3,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
name: `${material.name} - slab ${JSON.stringify(millerIndices)}`,
|
|
167
|
+
basis: newBasis.toJSON(),
|
|
168
|
+
lattice: newLattice.toJSON(),
|
|
169
|
+
// extra parameter for use in creating vacuum etc.
|
|
170
|
+
outOfPlaneAxisIndex,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export default {
|
|
175
|
+
generateConfig,
|
|
176
|
+
};
|
package/src/js/types.ts
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fixtures/** filter=lfs diff=lfs merge=lfs -text
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
|
|
3
|
+
import { Basis } from "../../../src/js/basis/basis";
|
|
4
|
+
import {
|
|
5
|
+
AsGeBasis,
|
|
6
|
+
C2H4,
|
|
7
|
+
C2H4Translated,
|
|
8
|
+
FeLiSiBasis,
|
|
9
|
+
LiFeSiBasis,
|
|
10
|
+
Na,
|
|
11
|
+
Na4Cl4,
|
|
12
|
+
Na4Cl4Cartesian,
|
|
13
|
+
} from "../enums";
|
|
14
|
+
import { assertDeepAlmostEqual } from "../utils";
|
|
15
|
+
|
|
16
|
+
describe("Basis", () => {
|
|
17
|
+
it("should return true if basises are equal", () => {
|
|
18
|
+
const basis1 = new Basis(FeLiSiBasis);
|
|
19
|
+
const basis2 = new Basis(LiFeSiBasis);
|
|
20
|
+
expect(basis1.isEqualTo(basis2)).to.be.equal(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should return true when basis is compared to its clone", () => {
|
|
24
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
25
|
+
expect(basis.isEqualTo(basis.clone())).to.be.equal(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should return jsonified basis", () => {
|
|
29
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
30
|
+
expect(basis.toJSON()).to.be.deep.almost.equal(Na4Cl4.basis);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should return true if cells are equal", () => {
|
|
34
|
+
const basis1 = new Basis(FeLiSiBasis);
|
|
35
|
+
const basis2 = new Basis(LiFeSiBasis);
|
|
36
|
+
expect(basis1.hasEquivalentCellTo(basis2)).to.be.equal(true);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Elements
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
it("should return Na4Cl4 as unitCellFormula", () => {
|
|
44
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
45
|
+
expect(basis.unitCellFormula).to.be.equal("Na4Cl4");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should return NaCl as formula", () => {
|
|
49
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
50
|
+
expect(basis.formula).to.be.equal("NaCl");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("should return elements", () => {
|
|
54
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
55
|
+
expect(basis.elements).to.be.deep.almost.equal(Na4Cl4.basis.elements);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should return unique elements", () => {
|
|
59
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
60
|
+
expect(basis.uniqueElements).to.be.deep.equal(["Na", "Cl"]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should return elements count", () => {
|
|
64
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
65
|
+
expect(basis.elementCounts).to.be.deep.equal([
|
|
66
|
+
{
|
|
67
|
+
value: "Na",
|
|
68
|
+
count: 4,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
value: "Cl",
|
|
72
|
+
count: 4,
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should set elements", () => {
|
|
78
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
79
|
+
basis.elements = AsGeBasis.elements;
|
|
80
|
+
expect(basis.elements).to.be.deep.equal(AsGeBasis.elements);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Coordinates
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
it("should return coordinates", () => {
|
|
88
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
89
|
+
expect(basis.coordinates).to.be.deep.almost.equal(Na4Cl4.basis.coordinates);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should set coordinates", () => {
|
|
93
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
94
|
+
basis.coordinates = AsGeBasis.coordinates;
|
|
95
|
+
expect(basis.coordinates).to.be.deep.almost.equal(AsGeBasis.coordinates);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Units
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
it("should return true if basis is in crystal units", () => {
|
|
103
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
104
|
+
expect(basis.isInCrystalUnits).to.be.equal(true);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("should convert crystal to cartesian", () => {
|
|
108
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
109
|
+
basis.toCartesian();
|
|
110
|
+
expect(basis.isInCartesianUnits).to.be.equal(true);
|
|
111
|
+
expect(basis.coordinates).to.be.deep.almost.equal(Na4Cl4Cartesian.basis.coordinates);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Atoms
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
it("should add a new atom", () => {
|
|
119
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
120
|
+
basis.addAtom({
|
|
121
|
+
element: "Ge",
|
|
122
|
+
coordinate: [0, 0.25, 0.25],
|
|
123
|
+
});
|
|
124
|
+
expect(basis.elements).to.be.deep.equal([
|
|
125
|
+
...Na4Cl4.basis.elements,
|
|
126
|
+
{
|
|
127
|
+
id: 8,
|
|
128
|
+
value: "Ge",
|
|
129
|
+
},
|
|
130
|
+
]);
|
|
131
|
+
expect(basis.coordinates).to.be.deep.almost.equal([
|
|
132
|
+
...Na4Cl4.basis.coordinates,
|
|
133
|
+
{
|
|
134
|
+
id: 8,
|
|
135
|
+
value: [0, 0.25, 0.25],
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("should remove an atom", () => {
|
|
141
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
142
|
+
basis.removeAtom({
|
|
143
|
+
id: 3,
|
|
144
|
+
element: "Na",
|
|
145
|
+
coordinate: [0.5, 0.5, 0],
|
|
146
|
+
});
|
|
147
|
+
expect(basis.elements.length).to.be.equal(7);
|
|
148
|
+
expect(basis.coordinates.length).to.be.equal(7);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("should return number of atoms", () => {
|
|
152
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
153
|
+
expect(basis.nAtoms).to.be.equal(8);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Hash
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
it("should return the string", () => {
|
|
161
|
+
const basis = new Basis(Na4Cl4.basis);
|
|
162
|
+
const string =
|
|
163
|
+
"Cl 0,0,0.5;Cl 0,0.5,0;Cl 0.5,0,0;Cl 0.5,0.5,0.5;Na 0,0,0;Na 0,0.5,0.5;Na 0.5,0,0.5;Na 0.5,0.5,0;";
|
|
164
|
+
expect(basis.getAsSortedString()).to.be.equal(string);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Representation
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
it("should return standard representation", () => {
|
|
172
|
+
const basis = new Basis(Na4Cl4Cartesian.basis);
|
|
173
|
+
expect(basis.standardRepresentation).to.be.deep.almost.equal(Na4Cl4.basis);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Minimum lattice size generated for a molecule with more than one atom.
|
|
178
|
+
* The minimumLatticeSize is the maximum pairwise distance between two atoms
|
|
179
|
+
* of the structure, C2H4 in this case.
|
|
180
|
+
*/
|
|
181
|
+
it("should return minimum lattice size for a molecule", () => {
|
|
182
|
+
const basis = new Basis(C2H4.basis);
|
|
183
|
+
const minimumLatticeSize = 3.162;
|
|
184
|
+
const latticeSize = basis.getMinimumLatticeSize();
|
|
185
|
+
expect(latticeSize).to.be.equal(minimumLatticeSize);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Minimum lattice size generated for a structure made up of a single atom.
|
|
190
|
+
* The minimumLatticeSize is the atomic radii of the atom, Na in this case, in units of angstroms.
|
|
191
|
+
*/
|
|
192
|
+
it("should return minimum lattice size for an atom", () => {
|
|
193
|
+
const basis = new Basis(Na.basis);
|
|
194
|
+
const minimumLatticeSize = 1.8;
|
|
195
|
+
const latticeSize = basis.getMinimumLatticeSize();
|
|
196
|
+
expect(latticeSize).to.be.equal(minimumLatticeSize);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
//* * Pairwise Distance */
|
|
200
|
+
it("should return max distance", () => {
|
|
201
|
+
const basis = new Basis(C2H4.basis);
|
|
202
|
+
const maxDistance = 1.581;
|
|
203
|
+
expect(basis.maxPairwiseDistance).to.be.equal(maxDistance);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
//* * Center of Coordinates */
|
|
207
|
+
it("should return center of coordinates", () => {
|
|
208
|
+
const basis = new Basis(C2H4.basis);
|
|
209
|
+
const centerOfCoordinatesArray = [0.3333, -0.0417, 0.0917];
|
|
210
|
+
const basisCenterOfCoordinatesPoint = basis.centerOfCoordinatesPoint;
|
|
211
|
+
assertDeepAlmostEqual(basisCenterOfCoordinatesPoint, centerOfCoordinatesArray);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
//* * Translation by Vector */
|
|
215
|
+
it("should return the updated basis coordinates", () => {
|
|
216
|
+
const basis = new Basis(C2H4.basis);
|
|
217
|
+
const translationVector = [1.6917, 1.9667, 2];
|
|
218
|
+
basis.translateByVector(translationVector);
|
|
219
|
+
assertDeepAlmostEqual(basis.coordinates, C2H4Translated.basis.coordinates);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Lattice } from "../../../src/js/lattice/lattice";
|
|
2
|
+
import { Si } from "../enums";
|
|
3
|
+
import { assertDeepAlmostEqual } from "../utils";
|
|
4
|
+
|
|
5
|
+
describe("Cell", () => {
|
|
6
|
+
it("should return scaled cell", () => {
|
|
7
|
+
const lattice = new Lattice(Si.lattice);
|
|
8
|
+
const expectedCell = {
|
|
9
|
+
tolerance: 1,
|
|
10
|
+
vector1: [10, 0, 0],
|
|
11
|
+
vector2: [0, 10, 0],
|
|
12
|
+
vector3: [0, 0, 10],
|
|
13
|
+
};
|
|
14
|
+
const actualCell = lattice.Cell.cloneAndScaleByMatrix([
|
|
15
|
+
[2, 0, 0],
|
|
16
|
+
[0, 2, 0],
|
|
17
|
+
[0, 0, 2],
|
|
18
|
+
]);
|
|
19
|
+
assertDeepAlmostEqual(expectedCell, actualCell);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { primitiveCell } from "../../../src/js/cell/primitive_cell";
|
|
2
|
+
import { Lattice } from "../../../src/js/lattice/lattice";
|
|
3
|
+
import { Na4Cl4 } from "../enums";
|
|
4
|
+
import { assertDeepAlmostEqual } from "../utils";
|
|
5
|
+
|
|
6
|
+
describe("Primitive Cell", () => {
|
|
7
|
+
it("should return primitive lattice", () => {
|
|
8
|
+
const lattice = new Lattice(Na4Cl4.lattice);
|
|
9
|
+
const actualPrimitiveCell = primitiveCell(lattice);
|
|
10
|
+
const expectedPrimitiveCell = [
|
|
11
|
+
[5.691694, 0, 0],
|
|
12
|
+
[0, 5.691694, 0],
|
|
13
|
+
[0, 0, 5.691694],
|
|
14
|
+
];
|
|
15
|
+
assertDeepAlmostEqual(expectedPrimitiveCell, actualPrimitiveCell);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
|
|
3
|
+
import { AtomicConstraints } from "../../../src/js/constraints/constraints";
|
|
4
|
+
import parsers from "../../../src/js/parsers/parsers";
|
|
5
|
+
import { atomicConstraints } from "../enums";
|
|
6
|
+
import { assertDeepAlmostEqual } from "../utils";
|
|
7
|
+
|
|
8
|
+
describe("AtomicConstraints", () => {
|
|
9
|
+
it("should return constraints as string", () => {
|
|
10
|
+
const constraints = new AtomicConstraints(atomicConstraints);
|
|
11
|
+
expect(constraints.getAsStringByIndex(0)).to.be.equal("1 1 0");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should return constraints as string with given map function", () => {
|
|
15
|
+
const constraints = new AtomicConstraints(atomicConstraints);
|
|
16
|
+
expect(
|
|
17
|
+
constraints.getAsStringByIndex(0, parsers.poscar.atomicConstraintsCharFromBool),
|
|
18
|
+
).to.be.equal("T T F");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should return [true, true, true] as constraints for the line without any constraints", () => {
|
|
22
|
+
const text = "Si 0 0 0 0 1 1\n Si 0.25 0.25 0.25";
|
|
23
|
+
const basis = parsers.xyz.toBasisConfig(text);
|
|
24
|
+
assertDeepAlmostEqual(basis.constraints[0].value, [false, true, true]);
|
|
25
|
+
assertDeepAlmostEqual(basis.constraints[1].value, [true, true, true]);
|
|
26
|
+
});
|
|
27
|
+
});
|