@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.
Files changed (176) hide show
  1. package/.babelrc +10 -0
  2. package/.eslintrc.json +11 -0
  3. package/.mocharc.json +5 -0
  4. package/.prettierignore +1 -0
  5. package/.prettierrc +6 -0
  6. package/LICENSE.md +15 -0
  7. package/README.md +167 -0
  8. package/dist/abstract/array_with_ids.d.ts +43 -0
  9. package/dist/abstract/array_with_ids.js +88 -0
  10. package/dist/abstract/scalar_with_id.d.ts +25 -0
  11. package/dist/abstract/scalar_with_id.js +44 -0
  12. package/dist/basis/basis.d.ts +269 -0
  13. package/dist/basis/basis.js +499 -0
  14. package/dist/basis/constrained_basis.d.ts +56 -0
  15. package/dist/basis/constrained_basis.js +90 -0
  16. package/dist/basis/types.d.ts +1 -0
  17. package/dist/basis/types.js +2 -0
  18. package/dist/cell/cell.d.ts +45 -0
  19. package/dist/cell/cell.js +88 -0
  20. package/dist/cell/conventional_cell.d.ts +22 -0
  21. package/dist/cell/conventional_cell.js +83 -0
  22. package/dist/cell/primitive_cell.d.ts +9 -0
  23. package/dist/cell/primitive_cell.js +166 -0
  24. package/dist/constants.d.ts +2 -0
  25. package/dist/constants.js +25 -0
  26. package/dist/constraints/constraints.d.ts +45 -0
  27. package/dist/constraints/constraints.js +49 -0
  28. package/dist/lattice/lattice.d.ts +104 -0
  29. package/dist/lattice/lattice.js +208 -0
  30. package/dist/lattice/lattice_bravais.d.ts +59 -0
  31. package/dist/lattice/lattice_bravais.js +120 -0
  32. package/dist/lattice/lattice_vectors.d.ts +46 -0
  33. package/dist/lattice/lattice_vectors.js +98 -0
  34. package/dist/lattice/reciprocal/lattice_reciprocal.d.ts +75 -0
  35. package/dist/lattice/reciprocal/lattice_reciprocal.js +148 -0
  36. package/dist/lattice/reciprocal/paths.d.ts +24 -0
  37. package/dist/lattice/reciprocal/paths.js +136 -0
  38. package/dist/lattice/reciprocal/symmetry_points.d.ts +8 -0
  39. package/dist/lattice/reciprocal/symmetry_points.js +866 -0
  40. package/dist/lattice/types.d.ts +49 -0
  41. package/dist/lattice/types.js +127 -0
  42. package/dist/lattice/unit_cell.d.ts +30 -0
  43. package/dist/lattice/unit_cell.js +31 -0
  44. package/dist/made.d.ts +40 -0
  45. package/dist/made.js +39 -0
  46. package/dist/material.d.ts +1562 -0
  47. package/dist/material.js +317 -0
  48. package/dist/math.d.ts +395 -0
  49. package/dist/math.js +7 -0
  50. package/dist/parsers/cif.d.ts +10 -0
  51. package/dist/parsers/cif.js +21 -0
  52. package/dist/parsers/errors.d.ts +5 -0
  53. package/dist/parsers/errors.js +11 -0
  54. package/dist/parsers/espresso.d.ts +10 -0
  55. package/dist/parsers/espresso.js +24 -0
  56. package/dist/parsers/native_format_parsers.d.ts +26 -0
  57. package/dist/parsers/native_format_parsers.js +52 -0
  58. package/dist/parsers/parsers.d.ts +13 -0
  59. package/dist/parsers/parsers.js +17 -0
  60. package/dist/parsers/poscar.d.ts +31 -0
  61. package/dist/parsers/poscar.js +180 -0
  62. package/dist/parsers/xyz.d.ts +62 -0
  63. package/dist/parsers/xyz.js +167 -0
  64. package/dist/parsers/xyz_combinatorial_basis.d.ts +64 -0
  65. package/dist/parsers/xyz_combinatorial_basis.js +241 -0
  66. package/dist/tools/basis.d.ts +22 -0
  67. package/dist/tools/basis.js +100 -0
  68. package/dist/tools/cell.d.ts +9 -0
  69. package/dist/tools/cell.js +39 -0
  70. package/dist/tools/index.d.ts +11 -0
  71. package/dist/tools/index.js +15 -0
  72. package/dist/tools/material.d.ts +25 -0
  73. package/dist/tools/material.js +54 -0
  74. package/dist/tools/supercell.d.ts +22 -0
  75. package/dist/tools/supercell.js +62 -0
  76. package/dist/tools/surface.d.ts +10 -0
  77. package/dist/tools/surface.js +147 -0
  78. package/dist/types.d.ts +3 -0
  79. package/dist/types.js +2 -0
  80. package/package.json +89 -0
  81. package/pyproject.toml +77 -0
  82. package/src/js/abstract/array_with_ids.ts +100 -0
  83. package/src/js/abstract/scalar_with_id.ts +53 -0
  84. package/src/js/basis/basis.ts +607 -0
  85. package/src/js/basis/constrained_basis.ts +107 -0
  86. package/src/js/basis/types.ts +1 -0
  87. package/src/js/cell/cell.ts +109 -0
  88. package/src/js/cell/conventional_cell.ts +89 -0
  89. package/src/js/cell/primitive_cell.ts +189 -0
  90. package/src/js/constants.js +4 -0
  91. package/src/js/constraints/constraints.ts +63 -0
  92. package/src/js/lattice/lattice.ts +229 -0
  93. package/src/js/lattice/lattice_bravais.ts +170 -0
  94. package/src/js/lattice/lattice_vectors.ts +126 -0
  95. package/src/js/lattice/reciprocal/lattice_reciprocal.js +155 -0
  96. package/src/js/lattice/reciprocal/paths.js +134 -0
  97. package/src/js/lattice/reciprocal/symmetry_points.ts +886 -0
  98. package/src/js/lattice/types.ts +142 -0
  99. package/src/js/lattice/unit_cell.ts +66 -0
  100. package/src/js/made.js +36 -0
  101. package/src/js/material.ts +398 -0
  102. package/src/js/math.js +6 -0
  103. package/src/js/parsers/cif.js +22 -0
  104. package/src/js/parsers/errors.js +7 -0
  105. package/src/js/parsers/espresso.ts +30 -0
  106. package/src/js/parsers/native_format_parsers.js +51 -0
  107. package/src/js/parsers/parsers.js +13 -0
  108. package/src/js/parsers/poscar.ts +201 -0
  109. package/src/js/parsers/xyz.ts +216 -0
  110. package/src/js/parsers/xyz_combinatorial_basis.js +243 -0
  111. package/src/js/tools/basis.js +116 -0
  112. package/src/js/tools/cell.js +36 -0
  113. package/src/js/tools/index.js +11 -0
  114. package/src/js/tools/material.js +60 -0
  115. package/src/js/tools/supercell.ts +80 -0
  116. package/src/js/tools/surface.js +176 -0
  117. package/src/js/types.ts +4 -0
  118. package/src/py/__init__.py +0 -0
  119. package/src/py/mat3ra/__init__.py +0 -0
  120. package/src/py/mat3ra/made/__init__.py +5 -0
  121. package/tests/.gitattributes +1 -0
  122. package/tests/fixtures/AsGe-basis.json +3 -0
  123. package/tests/fixtures/C2H4-translated.json +3 -0
  124. package/tests/fixtures/C2H4.json +3 -0
  125. package/tests/fixtures/FeLiSi-basis.json +3 -0
  126. package/tests/fixtures/FeO.json +3 -0
  127. package/tests/fixtures/Ge2-basis.json +3 -0
  128. package/tests/fixtures/Graphene.json +3 -0
  129. package/tests/fixtures/Graphene.poscar +3 -0
  130. package/tests/fixtures/H2+H-final.json +3 -0
  131. package/tests/fixtures/H2+H-image.json +3 -0
  132. package/tests/fixtures/H2+H-initial.json +3 -0
  133. package/tests/fixtures/H2O.poscar +3 -0
  134. package/tests/fixtures/LiFeSi-basis.json +3 -0
  135. package/tests/fixtures/Na.json +3 -0
  136. package/tests/fixtures/Na4Cl4-cartesian.json +3 -0
  137. package/tests/fixtures/Na4Cl4.json +3 -0
  138. package/tests/fixtures/Na4Cl4.poscar +3 -0
  139. package/tests/fixtures/Ni-hex.json +3 -0
  140. package/tests/fixtures/Ni-hex.poscar +3 -0
  141. package/tests/fixtures/OSi-basis.json +3 -0
  142. package/tests/fixtures/Si-hex.json +3 -0
  143. package/tests/fixtures/Si-hex.poscar +3 -0
  144. package/tests/fixtures/Si-pwscf.in +3 -0
  145. package/tests/fixtures/Si-slab.json +3 -0
  146. package/tests/fixtures/Si-supercell.json +3 -0
  147. package/tests/fixtures/Si.json +3 -0
  148. package/tests/fixtures/Si2-basis-repeated.json +3 -0
  149. package/tests/fixtures/Si2-basis.json +3 -0
  150. package/tests/fixtures/Zr1H23Zr1H1.json +3 -0
  151. package/tests/fixtures/Zr1H23Zr1H1.poscar +3 -0
  152. package/tests/fixtures/atomic-constraints.json +3 -0
  153. package/tests/js/basis/basis.js +221 -0
  154. package/tests/js/cell/cell.js +21 -0
  155. package/tests/js/cell/primitive_cell.js +17 -0
  156. package/tests/js/constraints/constraints.js +27 -0
  157. package/tests/js/enums.js +40 -0
  158. package/tests/js/lattice/lattice.js +31 -0
  159. package/tests/js/lattice/lattice_bravais.js +17 -0
  160. package/tests/js/lattice/lattice_reciprocal.js +99 -0
  161. package/tests/js/lattice/lattice_vectors.js +10 -0
  162. package/tests/js/material.test.js +11 -0
  163. package/tests/js/parsers/espresso.js +12 -0
  164. package/tests/js/parsers/native_formats.js +30 -0
  165. package/tests/js/parsers/poscar.js +21 -0
  166. package/tests/js/parsers/xyz.js +25 -0
  167. package/tests/js/parsers/xyz_combinatorial_basis.js +153 -0
  168. package/tests/js/setup.js +6 -0
  169. package/tests/js/tools/basis.js +18 -0
  170. package/tests/js/tools/supercell.js +23 -0
  171. package/tests/js/tools/surface.js +12 -0
  172. package/tests/js/utils.js +17 -0
  173. package/tests/py/__init__.py +0 -0
  174. package/tests/py/unit/__init__.py +0 -0
  175. package/tests/py/unit/test_sample.py +10 -0
  176. package/tsconfig.json +3 -0
@@ -0,0 +1,170 @@
1
+ import { LatticeImplicitSchema, LatticeTypeSchema } from "@mat3ra/esse/lib/js/types";
2
+
3
+ import constants from "../constants";
4
+ import math from "../math";
5
+ import { LATTICE_TYPE_CONFIGS, Vector, VectorsAsArray } from "./types";
6
+
7
+ export type Units = Required<LatticeImplicitSchema>["units"];
8
+
9
+ export interface FromVectorsProps {
10
+ a: Vector; // vector of the lattice.
11
+ b: Vector; // vector of the lattice.
12
+ c: Vector; // vector of the lattice.
13
+ alat?: number; // scaling factor for the vector coordinates, defaults to 1.
14
+ units?: Units["length"]; // units for the coordinates (eg. angstrom, crystal).
15
+ type?: LatticeTypeSchema; // type of the lattice to be created, defaults to TRI when not provided.
16
+ skipRounding?: boolean; // whether to skip rounding the resulting lattice values, defaults to `false`.
17
+ }
18
+
19
+ /*
20
+ * @summary: class that holds parameters of a Bravais Lattice: a, b, c, alpha, beta, gamma + corresponding units.
21
+ * When stored as class variables units for lengths are always "angstrom"s, angle - "degree"s
22
+ */
23
+ export class LatticeBravais implements LatticeImplicitSchema {
24
+ a: number;
25
+
26
+ b: number;
27
+
28
+ c: number;
29
+
30
+ alpha: number;
31
+
32
+ beta: number;
33
+
34
+ gamma: number;
35
+
36
+ units: Units;
37
+
38
+ type: LatticeImplicitSchema["type"];
39
+
40
+ /**
41
+ * Create a Bravais lattice.
42
+ */
43
+ constructor(config: Partial<LatticeImplicitSchema>) {
44
+ const {
45
+ a = 1, // default lattice is cubic with unity in edge sizes
46
+ b = a,
47
+ c = a,
48
+ alpha = 90,
49
+ beta = alpha,
50
+ gamma = alpha,
51
+ // if we do not know what lattice type this is => set to TRI
52
+ type = "TRI",
53
+ units = {
54
+ length: "angstrom",
55
+ angle: "degree",
56
+ },
57
+ } = config;
58
+
59
+ const k =
60
+ constants.units.bohr === units.length ? constants.coefficients.BOHR_TO_ANGSTROM : 1;
61
+
62
+ this.a = a * k;
63
+ this.b = b * k;
64
+ this.c = c * k;
65
+ this.alpha = alpha;
66
+ this.beta = beta;
67
+ this.gamma = gamma;
68
+ this.type = type;
69
+ this.units = units;
70
+ }
71
+
72
+ static _roundValue(x: number): number {
73
+ return math.precise(math.roundToZero(x));
74
+ }
75
+
76
+ /**
77
+ * Create a Bravais lattice from vectors.
78
+ */
79
+ static fromVectors({
80
+ a,
81
+ b,
82
+ c,
83
+ alat = 1,
84
+ units = "angstrom",
85
+ type = "TRI",
86
+ skipRounding = false,
87
+ }: FromVectorsProps) {
88
+ const roundValue = skipRounding ? (x: number) => x : this._roundValue;
89
+
90
+ return new (this.prototype.constructor as typeof LatticeBravais)({
91
+ // @ts-ignore
92
+ a: roundValue(math.vlen(a) * alat),
93
+ // @ts-ignore
94
+ b: roundValue(math.vlen(b) * alat),
95
+ // @ts-ignore
96
+ c: roundValue(math.vlen(c) * alat),
97
+ alpha: roundValue(math.angle(b, c, "deg")),
98
+ beta: roundValue(math.angle(a, c, "deg")),
99
+ gamma: roundValue(math.angle(a, b, "deg")),
100
+ // initially we do not know what lattice type this is => set to TRI
101
+ type,
102
+ units: {
103
+ length: units,
104
+ angle: "degree",
105
+ },
106
+ });
107
+ }
108
+
109
+ /**
110
+ * See fromVectors above.
111
+ */
112
+ static fromVectorArrays(array: VectorsAsArray, type: LatticeTypeSchema, skipRounding = true) {
113
+ return this.fromVectors({
114
+ a: array[0],
115
+ b: array[1],
116
+ c: array[2],
117
+ type,
118
+ skipRounding, // do not round the values to avoid loosing precision by default
119
+ });
120
+ }
121
+
122
+ /**
123
+ * Get the list of editable keys (eg. 'a', 'alpha') for the current lattice.
124
+ * @return {Object}
125
+ * @example {a: true, b: false, c: false, alpha: true, beta: false, gamma: false}
126
+ */
127
+ get editables() {
128
+ const object = {};
129
+ const editablesList = LATTICE_TYPE_CONFIGS.find(
130
+ (entry) => entry.code === this.type,
131
+ )?.editables;
132
+ // ["a", "gamma"] => {a: true, gamma: true}
133
+ if (editablesList) {
134
+ editablesList.forEach((element) => {
135
+ Object.assign(object, {
136
+ [element]: true,
137
+ });
138
+ });
139
+ }
140
+
141
+ return object;
142
+ }
143
+
144
+ /**
145
+ * Serialize class instance to JSON.
146
+ * @example As below:
147
+ {
148
+ "a" : 3.867,
149
+ "b" : 3.867,
150
+ "c" : 3.867,
151
+ "alpha" : 60,
152
+ "beta" : 60,
153
+ "gamma" : 60,
154
+ "units" : {
155
+ "length" : "angstrom",
156
+ "angle" : "degree"
157
+ },
158
+ "type" : "FCC"
159
+ }
160
+ */
161
+ toJSON(): LatticeImplicitSchema {
162
+ return {
163
+ ...this,
164
+ units: {
165
+ length: this.units.length,
166
+ angle: this.units.angle,
167
+ },
168
+ };
169
+ }
170
+ }
@@ -0,0 +1,126 @@
1
+ import { LatticeExplicitUnit, LatticeImplicitSchema } from "@mat3ra/esse/lib/js/types";
2
+
3
+ import { primitiveCell } from "../cell/primitive_cell";
4
+ import constants from "../constants";
5
+ import math from "../math";
6
+ import { Vector } from "./types";
7
+
8
+ type RequiredLatticeExplicitUnit = Required<LatticeExplicitUnit>;
9
+
10
+ export interface BravaisConfigProps extends Partial<LatticeImplicitSchema> {
11
+ isConventional?: boolean;
12
+ }
13
+
14
+ /*
15
+ * @summary: class that holds parameters of a Bravais Lattice: a, b, c, alpha, beta, gamma + corresponding units.
16
+ * When stored as class variables units for lengths are always "angstrom"s, angle - "degree"s
17
+ */
18
+ export class LatticeVectors implements RequiredLatticeExplicitUnit {
19
+ a: RequiredLatticeExplicitUnit["a"];
20
+
21
+ b: RequiredLatticeExplicitUnit["b"];
22
+
23
+ c: RequiredLatticeExplicitUnit["c"];
24
+
25
+ alat: RequiredLatticeExplicitUnit["alat"];
26
+
27
+ units: RequiredLatticeExplicitUnit["units"];
28
+
29
+ /**
30
+ * Create a Bravais lattice.
31
+ */
32
+ constructor(config: LatticeExplicitUnit) {
33
+ const { a, b, c, alat = 1, units = "angstrom" } = config;
34
+ const k = constants.units.bohr === units ? constants.coefficients.BOHR_TO_ANGSTROM : 1;
35
+
36
+ this.a = a.map((x) => x * k) as Vector;
37
+ this.b = b.map((x) => x * k) as Vector;
38
+ this.c = c.map((x) => x * k) as Vector;
39
+ this.alat = alat;
40
+ this.units = "angstrom";
41
+ }
42
+
43
+ static _roundValue(arr: number[]): number[] {
44
+ return arr.map((el) => math.precise(math.roundToZero(el)));
45
+ }
46
+
47
+ /*
48
+ * Constructs a Bravais lattice from lattice vectors
49
+ * Supports conventional lattice as parameters and primitive too.
50
+ * Algorithm from http://pymatgen.org/_modules/pymatgen/core/lattice.html (from_params)
51
+ * For parameters see `LatticeBravais.constructor`.
52
+ */
53
+ static fromBravais({
54
+ a = 1, // default lattice is cubic with unity in edge sizes
55
+ b = a,
56
+ c = a,
57
+ alpha = 90,
58
+ beta = 90,
59
+ gamma = 90,
60
+ units = {
61
+ length: "angstrom",
62
+ angle: "degree",
63
+ },
64
+ type = "TRI",
65
+ isConventional = false,
66
+ }: BravaisConfigProps) {
67
+ // use "direct" lattice constructor for primitive lattice
68
+ // eslint-disable-next-line no-param-reassign
69
+ if (!isConventional) type = "TRI";
70
+
71
+ // set precision and remove JS floating point artifacts
72
+ const [vectorA, vectorB, vectorC] = primitiveCell({
73
+ a,
74
+ b,
75
+ c,
76
+ alpha,
77
+ beta,
78
+ gamma,
79
+ units,
80
+ type,
81
+ });
82
+
83
+ return new LatticeVectors({
84
+ a: vectorA,
85
+ b: vectorB,
86
+ c: vectorC,
87
+ alat: 1,
88
+ });
89
+ }
90
+
91
+ get vectorArrays(): [Vector, Vector, Vector] {
92
+ return [this.a, this.b, this.c];
93
+ }
94
+
95
+ /**
96
+ * Serialize class instance to JSON.
97
+ * @example As below:
98
+ {
99
+ "a" : [
100
+ 3.34892,
101
+ 0,
102
+ 1.9335
103
+ ],
104
+ "b" : [
105
+ 1.116307,
106
+ 3.157392,
107
+ 1.9335
108
+ ],
109
+ "c" : [
110
+ 0,
111
+ 0,
112
+ 3.867
113
+ ],
114
+ "alat" : 1,
115
+ "units" : "angstrom"
116
+ }
117
+ */
118
+ toJSON(): RequiredLatticeExplicitUnit {
119
+ return {
120
+ ...this,
121
+ a: LatticeVectors._roundValue(this.a),
122
+ b: LatticeVectors._roundValue(this.b),
123
+ c: LatticeVectors._roundValue(this.c),
124
+ };
125
+ }
126
+ }
@@ -0,0 +1,155 @@
1
+ import { ATOMIC_COORD_UNITS, units as UNITS } from "@exabyte-io/code.js/dist/constants";
2
+ import almostEqual from "array-almost-equal";
3
+ import lodash from "lodash";
4
+
5
+ import math from "../../math";
6
+ import { Lattice } from "../lattice";
7
+ import { paths } from "./paths";
8
+ import { symmetryPoints } from "./symmetry_points";
9
+
10
+ export class ReciprocalLattice extends Lattice {
11
+ /**
12
+ * Get reciprocal vectors for the current Lattice in cartesian (2pi / a) units
13
+ * @return {Array[]}
14
+ */
15
+ get reciprocalVectors() {
16
+ const vectors_ = this.vectors.vectorArrays;
17
+ const a = math.vlen(vectors_[0]);
18
+ const divider = math.multiply(vectors_[0], math.cross(vectors_[1], vectors_[2])) / a;
19
+ return [
20
+ math.multiply(math.cross(vectors_[1], vectors_[2]), 1 / divider),
21
+ math.multiply(math.cross(vectors_[2], vectors_[0]), 1 / divider),
22
+ math.multiply(math.cross(vectors_[0], vectors_[1]), 1 / divider),
23
+ ];
24
+ }
25
+
26
+ /**
27
+ * Norms of reciprocal vectors.
28
+ * @return {number[]}
29
+ */
30
+ get reciprocalVectorNorms() {
31
+ return this.reciprocalVectors.map((vec) => math.norm(vec));
32
+ }
33
+
34
+ /**
35
+ * Ratio of reciprocal vector norms scaled by the inverse of the largest component.
36
+ * @return {number[]}
37
+ */
38
+ get reciprocalVectorRatios() {
39
+ const norms = this.reciprocalVectorNorms;
40
+ const maxNorm = math.max(...norms);
41
+ return norms.map((n) => n / maxNorm);
42
+ }
43
+
44
+ /**
45
+ * Get point (in crystal coordinates) in cartesian coordinates.
46
+ * @param {Array} point - point in 3D space
47
+ * @return {Array}
48
+ */
49
+ getCartesianCoordinates(point) {
50
+ return math.multiply(point, this.reciprocalVectors);
51
+ }
52
+
53
+ /**
54
+ * Get the list of high-symmetry points for the current lattice.
55
+ * @return {Object[]}
56
+ */
57
+ get symmetryPoints() {
58
+ return symmetryPoints(this);
59
+ }
60
+
61
+ /**
62
+ * Get the default path in reciprocal space for the current lattice.
63
+ * @return {Array[]}
64
+ */
65
+ get defaultKpointPath() {
66
+ return paths[this.typeExtended] || paths[this.type];
67
+ }
68
+
69
+ /**
70
+ * Find/mark the high symmetry points on a list with raw data and return the edited list.
71
+ * @param {Array} dataPoints - list of point coordinates
72
+ * @return {Object[]}
73
+ */
74
+ extractKpointPath(dataPoints = []) {
75
+ const kpointPath = [];
76
+ const symmPoints = this.symmetryPoints;
77
+
78
+ dataPoints.forEach((point, index) => {
79
+ const symmPoint = symmPoints.find((x) => {
80
+ return almostEqual(x.coordinates, point, 1e-4);
81
+ });
82
+ if (symmPoint) {
83
+ kpointPath.push({
84
+ point: symmPoint.point,
85
+ steps: index,
86
+ coordinates: symmPoint.coordinates,
87
+ });
88
+ }
89
+ });
90
+ return kpointPath;
91
+ }
92
+
93
+ /**
94
+ * Calculate grid dimension based on reciprocal lattice vectors.
95
+ * @param {number} nPoints - Total number of points
96
+ * @param {number} index - Index of reciprocal vector
97
+ * @return {number} - Grid dimension in direction of reciprocal vector
98
+ * @todo This could be moved to a separate KGrid class.
99
+ */
100
+ calculateDimension(nPoints, index) {
101
+ const norms = this.reciprocalVectorNorms;
102
+ const [j, k] = [0, 1, 2].filter((i) => i !== index); // get indices of other two dimensions
103
+ const N = math.cbrt((nPoints * norms[index] ** 2) / (norms[j] * norms[k]));
104
+ return math.max(1, math.ceil(N));
105
+ }
106
+
107
+ /**
108
+ * Calculate grid dimensions from total number of k-points.
109
+ * @param {number} nKpoints - Total number of k-points.
110
+ * @return {number[]} - Grid dimensions
111
+ */
112
+ getDimensionsFromPointsCount(nKpoints) {
113
+ const indices = [0, 1, 2];
114
+ return indices.map((i) => this.calculateDimension(nKpoints, i));
115
+ }
116
+
117
+ get conversionTable() {
118
+ const { a } = this;
119
+ return {
120
+ [ATOMIC_COORD_UNITS.cartesian]: {
121
+ [UNITS.angstrom]: (2 * math.PI) / a,
122
+ },
123
+ [UNITS.angstrom]: {
124
+ [ATOMIC_COORD_UNITS.cartesian]: a / (2 * math.PI),
125
+ },
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Calculate grid dimensions from k-point spacing, i.e.
131
+ * the maximum distance between adjacent points along a reciprocal axis.
132
+ * Note: just as the lattice vectors spacing is in cartesian (2pi / a) units by default
133
+ * @param {number} spacing - maximum Spacing between k-points
134
+ * @param {string} units - units of spacing parameter (default: 2pi / a)
135
+ * @return {number[]}
136
+ */
137
+ getDimensionsFromSpacing(spacing, units = ATOMIC_COORD_UNITS.cartesian) {
138
+ const factor = this.conversionTable[units][ATOMIC_COORD_UNITS.cartesian] || 1;
139
+ return this.reciprocalVectorNorms.map((norm) => {
140
+ return math.max(1, math.ceil(lodash.round(norm / (spacing * factor), 4)));
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Calculate grid spacing as average of spacing along individual reciprocal axes.
146
+ * @param {number[]} dimensions - Array of dimensions
147
+ * @param {string} units - units of spacing parameter (default: 2pi / a)
148
+ * @return {number} - average grid spacing
149
+ */
150
+ getSpacingFromDimensions(dimensions, units = ATOMIC_COORD_UNITS.cartesian) {
151
+ const factor = this.conversionTable[ATOMIC_COORD_UNITS.cartesian][units] || 1;
152
+ const norms = this.reciprocalVectorNorms;
153
+ return factor * math.mean(dimensions.map((dim, i) => norms[i] / math.max(1, dim)));
154
+ }
155
+ }
@@ -0,0 +1,134 @@
1
+ import _ from "underscore";
2
+
3
+ /**
4
+ * Default kpoing paths according to:
5
+ * [AFLOW](https://arxiv.org/abs/1004.2974) methodology.
6
+ * Paths are split in parts for clarity.
7
+ */
8
+ const points = {
9
+ CUB: [
10
+ ["Г", "X", "M", "Г", "R", "X"],
11
+ ["M", "R"],
12
+ ],
13
+ BCC: [
14
+ ["Г", "H", "N", "Г", "P", "H"],
15
+ ["P", "N"],
16
+ ],
17
+ FCC: [
18
+ ["Г", "X", "W", "K", "Г", "L", "U", "W", "L"],
19
+ ["U", "X"],
20
+ ],
21
+ TET: [
22
+ ["Г", "X", "M", "Г", "Z", "R", "A", "Z"],
23
+ ["X", "R"],
24
+ ["M", "A"],
25
+ ],
26
+ "BCT-1": [
27
+ ["Г", "X", "M", "Г", "Z", "P", "N", "Z1", "M"],
28
+ ["X", "P"],
29
+ ],
30
+ "BCT-2": [
31
+ ["Г", "X", "Y", "∑", "Г", "Z", "∑1", "N", "P", "Y1", "Z"],
32
+ ["X", "P"],
33
+ ],
34
+ ORC: [
35
+ ["Г", "X", "S", "Y", "Г", "Z", "U", "R", "T", "Z"],
36
+ ["Y", "T"],
37
+ ["U", "X"],
38
+ ["S", "R"],
39
+ ],
40
+ "ORCF-1": [
41
+ ["Г", "Y", "T", "Z", "Г", "X", "A1", "Y"],
42
+ ["T", "X1"],
43
+ ["X", "A", "Z"],
44
+ ["L", "Г"],
45
+ ],
46
+ "ORCF-2": [
47
+ ["Г", "Y", "C", "D", "X", "Г", "Z", "D1", "H", "C"],
48
+ ["C1", "Z"],
49
+ ["X", "H1"],
50
+ ["H", "Y"],
51
+ ["L", "Г"],
52
+ ],
53
+ "ORCF-3": [
54
+ ["Г", "Y", "T", "Z", "Г", "X", "A1", "Y"],
55
+ ["X", "A", "Z"],
56
+ ["L", "Г"],
57
+ ],
58
+ ORCI: [
59
+ ["Г", "X", "L", "T", "W", "R", "X1", "Z", "Г", "Y", "S", "W"],
60
+ ["L1", "Y"],
61
+ ["Y1", "Z"],
62
+ ],
63
+ ORCC: [
64
+ ["Г", "X", "S", "R", "A", "Z", "Г", "Y", "X1", "A1", "T", "Y"],
65
+ ["Z", "T"],
66
+ ],
67
+ HEX: [
68
+ ["Г", "M", "K", "Г", "A", "L", "H", "A"],
69
+ ["L", "M"],
70
+ ["K", "H"],
71
+ ],
72
+ "RHL-1": [
73
+ ["Г", "L", "B1"],
74
+ ["B", "Z", "Г", "X"],
75
+ ["Q", "F", "P1", "Z"],
76
+ ["L", "P"],
77
+ ],
78
+ "RHL-2": [["Г", "P", "Z", "Q", "Г", "F", "P1", "Q1", "L", "Z"]],
79
+ MCL: [
80
+ ["Г", "Y", "H", "C", "E", "M1", "A", "X", "H1"],
81
+ ["M", "D", "Z"],
82
+ ["Y", "D"],
83
+ ],
84
+ "MCLC-1": [
85
+ ["Г", "Y", "Г", "L", "I"],
86
+ ["I1", "Z", "F1"],
87
+ ["Y", "X1"],
88
+ ["X", "Г", "N"],
89
+ ["M", "Г"],
90
+ ],
91
+ "MCLC-2": [
92
+ ["Г", "Y", "F", "L", "I"],
93
+ ["I1", "Z", "F1"],
94
+ ["N", "Г", "M"],
95
+ ],
96
+ "MCLC-3": [
97
+ ["Г", "Y", "F", "H", "Z", "I", "F1"],
98
+ ["H1", "Y1", "X", "Г", "N"],
99
+ ["M", "Г"],
100
+ ],
101
+ "MCLC-4": [
102
+ ["Г", "Y", "F", "H", "Z", "I"],
103
+ ["H1", "Y1", "X", "Г", "N"],
104
+ ["M", "Г"],
105
+ ],
106
+ "MCLC-5": [
107
+ ["Г", "Y", "F", "L", "I"],
108
+ ["I1", "Z", "H", "F1"],
109
+ ["H1", "Y1", "X", "Г", "N"],
110
+ ["M", "Г"],
111
+ ],
112
+ TRI: [
113
+ ["X", "Г", "Y"],
114
+ ["L", "Г", "Z"],
115
+ ["N", "Г", "M"],
116
+ ["R", "Г"],
117
+ ],
118
+ };
119
+
120
+ export const paths = _.each(points, (val, key, obj) => {
121
+ // merge sub-arrays
122
+ // eslint-disable-next-line no-param-reassign
123
+ val = val.reduce((a, b) => a.concat(b));
124
+
125
+ _.each(val, (el, idx, list) => {
126
+ list[idx] = {
127
+ point: el,
128
+ // TODO: calculate number of steps based on distance in k-space
129
+ steps: 10,
130
+ };
131
+ });
132
+
133
+ obj[key] = val;
134
+ });