@mat3ra/made 2026.7.4-0 → 2026.7.13-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/dist/js/basis/basis.js +8 -8
- package/dist/js/basis/coordinates.js +2 -2
- package/dist/js/cell/cell.js +11 -10
- package/dist/js/cell/primitive_cell.js +18 -19
- package/dist/js/lattice/lattice.js +25 -23
- package/dist/js/lattice/reciprocal/lattice_reciprocal.js +16 -16
- package/dist/js/parsers/poscar.js +1 -2
- package/dist/js/parsers/xyz_combinatorial_basis.js +2 -2
- package/dist/js/tools/basis.js +3 -3
- package/dist/js/tools/cell.js +3 -3
- package/dist/js/tools/material.js +3 -3
- package/dist/js/tools/supercell.js +3 -3
- package/dist/js/tools/surface.js +14 -12
- package/package.json +3 -2
- package/pyproject.toml +1 -1
- package/src/js/basis/basis.ts +9 -8
- package/src/js/basis/coordinates.ts +3 -2
- package/src/js/cell/cell.ts +12 -10
- package/src/js/cell/primitive_cell.ts +23 -19
- package/src/js/lattice/lattice.ts +25 -23
- package/src/js/lattice/reciprocal/lattice_reciprocal.ts +19 -18
- package/src/js/parsers/poscar.ts +2 -2
- package/src/js/parsers/xyz_combinatorial_basis.ts +3 -2
- package/src/js/tools/basis.ts +4 -3
- package/src/js/tools/cell.ts +4 -3
- package/src/js/tools/material.ts +5 -4
- package/src/js/tools/supercell.ts +4 -3
- package/src/js/tools/surface.ts +18 -12
- package/src/py/mat3ra/made/basis/__init__.py +6 -3
- package/src/py/mat3ra/made/tools/analyze/solid_solution_analyzer.py +171 -0
- package/src/py/mat3ra/made/tools/analyze/utils.py +25 -0
- package/src/py/mat3ra/made/tools/build/defective_structures/three_dimensional/__init__.py +1 -0
- package/src/py/mat3ra/made/tools/build/defective_structures/three_dimensional/solid_solution/__init__.py +9 -0
- package/src/py/mat3ra/made/tools/build/defective_structures/three_dimensional/solid_solution/builder.py +37 -0
- package/src/py/mat3ra/made/tools/build/defective_structures/three_dimensional/solid_solution/configuration.py +30 -0
- package/src/py/mat3ra/made/tools/build/defective_structures/three_dimensional/solid_solution/enums.py +8 -0
- package/src/py/mat3ra/made/tools/build/defective_structures/three_dimensional/solid_solution/helpers.py +76 -0
- package/src/py/mat3ra/made/tools/build_components/entities/auxiliary/zero_dimensional/crystal_site/crystal_site.py +3 -2
- package/src/py/mat3ra/made/tools/build_components/entities/auxiliary/zero_dimensional/point_defect_site/builder.py +11 -10
- package/src/py/mat3ra/made/tools/build_components/operations/core/combinations/merge/builder.py +9 -0
- package/src/py/mat3ra/made/tools/helpers.py +2 -0
- package/tests/fixtures/hashes.json +3 -0
- package/tests/js/cell/cell.ts +1 -1
- package/tests/js/fixtures.ts +7 -1
- package/tests/js/material.test.ts +8 -1
- package/tests/py/unit/test_material.py +10 -0
- package/tests/py/unit/test_tools_build_defect/test_solid_solution.py +90 -0
package/dist/js/basis/basis.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.Basis = void 0;
|
|
|
4
4
|
// @ts-ignore
|
|
5
5
|
const periodic_table_js_1 = require("@exabyte-io/periodic-table.js");
|
|
6
6
|
const entity_1 = require("@mat3ra/code/dist/js/entity");
|
|
7
|
-
const
|
|
7
|
+
const utils_1 = require("@mat3ra/utils");
|
|
8
8
|
const lodash_1 = require("lodash");
|
|
9
9
|
const cell_1 = require("../cell/cell");
|
|
10
10
|
const constants_1 = require("../constants");
|
|
@@ -163,7 +163,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
163
163
|
}
|
|
164
164
|
toStandardRepresentation() {
|
|
165
165
|
this.toCrystal();
|
|
166
|
-
this._coordinates.mapArrayInPlace((point) => point.map((x) =>
|
|
166
|
+
this._coordinates.mapArrayInPlace((point) => point.map((x) => utils_1.Utils.math.mod(x)));
|
|
167
167
|
}
|
|
168
168
|
/** A representation where all coordinates are within 0 and 1 in crystal units */
|
|
169
169
|
get standardRepresentation() {
|
|
@@ -237,7 +237,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
237
237
|
get formula() {
|
|
238
238
|
const counts = this.uniqueElementCountsSortedByElectronegativity;
|
|
239
239
|
const countsValues = (0, lodash_1.values)(counts);
|
|
240
|
-
const gcd = countsValues.length > 1 ?
|
|
240
|
+
const gcd = countsValues.length > 1 ? utils_1.Utils.math.gcd(...countsValues) : countsValues[0];
|
|
241
241
|
return (0, lodash_1.toPairs)(counts)
|
|
242
242
|
.map(([element, count]) => element + (count / gcd === 1 ? "" : count / gcd))
|
|
243
243
|
.reduce((acc, part) => acc + part, "");
|
|
@@ -290,7 +290,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
290
290
|
const element = entry[0];
|
|
291
291
|
const coordinate = entry[1];
|
|
292
292
|
const atomicLabel = entry[2];
|
|
293
|
-
const toleratedCoordinate = coordinate.map((x) =>
|
|
293
|
+
const toleratedCoordinate = coordinate.map((x) => utils_1.Utils.math.roundCustom(x, constants_1.HASH_TOLERANCE));
|
|
294
294
|
return `${element}${atomicLabel} ${toleratedCoordinate.join()}`;
|
|
295
295
|
});
|
|
296
296
|
return `${standardRep.sort().join(";")};`;
|
|
@@ -361,7 +361,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
361
361
|
hasEquivalentCellTo(anotherBasisClsInstance) {
|
|
362
362
|
return !this.cell.vectorArrays
|
|
363
363
|
.map((vector, idx) => {
|
|
364
|
-
return
|
|
364
|
+
return utils_1.Utils.math.vEqualWithTolerance(vector, anotherBasisClsInstance.cell.vectorArrays[idx]);
|
|
365
365
|
})
|
|
366
366
|
.some((x) => !x);
|
|
367
367
|
}
|
|
@@ -380,7 +380,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
380
380
|
const maxDistance = this.maxPairwiseDistance;
|
|
381
381
|
const minDistance = this.minPairwiseDistance;
|
|
382
382
|
const widthRatio = maxDistance > 0 ? minDistance / maxDistance : 1;
|
|
383
|
-
const latticeScalingFactor =
|
|
383
|
+
const latticeScalingFactor = utils_1.Utils.math.almostEqual(widthRatio, 1)
|
|
384
384
|
? lattice_1.diatomicLatticePaddingFactor
|
|
385
385
|
: lattice_1.molecularLatticePaddingFactor;
|
|
386
386
|
const moleculeLatticeSize = maxDistance * latticeScalingFactor;
|
|
@@ -404,7 +404,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
404
404
|
const tolerance = overlapCoefficient *
|
|
405
405
|
((0, periodic_table_js_1.getElementAtomicRadius)(el1) + (0, periodic_table_js_1.getElementAtomicRadius)(el2)); // in angstroms
|
|
406
406
|
// @ts-ignore
|
|
407
|
-
const distance =
|
|
407
|
+
const distance = utils_1.Utils.math.vDist(entry1.value, entry2.value);
|
|
408
408
|
if (distance < tolerance) {
|
|
409
409
|
overlaps.push({
|
|
410
410
|
id1: i,
|
|
@@ -446,7 +446,7 @@ class Basis extends entity_1.InMemoryEntity {
|
|
|
446
446
|
if (this._elements.values.length >= 2) {
|
|
447
447
|
for (let i = 0; i < this._elements.values.length; i++) {
|
|
448
448
|
for (let j = i + 1; j < this._elements.values.length; j++) {
|
|
449
|
-
const distance =
|
|
449
|
+
const distance = utils_1.Utils.math.vDist(this._coordinates.getElementValueByIndex(i), this._coordinates.getElementValueByIndex(j));
|
|
450
450
|
if (!distance)
|
|
451
451
|
continue;
|
|
452
452
|
if (extremum === "max" && distance > resultDistance) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Coordinates = exports.Coordinate = void 0;
|
|
4
4
|
const code_1 = require("@mat3ra/code");
|
|
5
|
-
const
|
|
5
|
+
const utils_1 = require("@mat3ra/utils");
|
|
6
6
|
const underscore_string_1 = require("underscore.string");
|
|
7
7
|
class Coordinate extends code_1.RoundedValueWithId {
|
|
8
8
|
constructor({ value, id }) {
|
|
@@ -58,7 +58,7 @@ class Coordinates extends code_1.RoundedArrayWithIds {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
getCenterPoint() {
|
|
61
|
-
const transposed =
|
|
61
|
+
const transposed = utils_1.Utils.math.transpose(this.values);
|
|
62
62
|
const center = [0, 0, 0];
|
|
63
63
|
for (let i = 0; i < 3; i++) {
|
|
64
64
|
const axisCoords = transposed[i];
|
package/dist/js/cell/cell.js
CHANGED
|
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.Cell = void 0;
|
|
7
7
|
const code_1 = require("@mat3ra/code");
|
|
8
|
-
const
|
|
8
|
+
const utils_1 = require("@mat3ra/utils");
|
|
9
9
|
const constants_1 = __importDefault(require("../constants"));
|
|
10
|
-
const MATRIX =
|
|
11
|
-
const MULT =
|
|
12
|
-
const INV =
|
|
10
|
+
const MATRIX = utils_1.Utils.math.matrix;
|
|
11
|
+
const MULT = utils_1.Utils.math.multiply;
|
|
12
|
+
const INV = utils_1.Utils.math.inv;
|
|
13
13
|
// @ts-ignore
|
|
14
14
|
const MATRIX_MULT = (...args) => MULT(...args.map((x) => MATRIX(x))).toArray();
|
|
15
15
|
class Cell {
|
|
@@ -44,10 +44,10 @@ class Cell {
|
|
|
44
44
|
return [this._a.valueRounded, this._b.valueRounded, this._c.valueRounded];
|
|
45
45
|
}
|
|
46
46
|
get volume() {
|
|
47
|
-
return
|
|
47
|
+
return utils_1.Utils.math.det(this.vectorArrays);
|
|
48
48
|
}
|
|
49
49
|
get volumeRounded() {
|
|
50
|
-
return
|
|
50
|
+
return utils_1.Utils.math.roundArrayOrNumber(this.volume, Cell.roundPrecision);
|
|
51
51
|
}
|
|
52
52
|
clone() {
|
|
53
53
|
return new Cell({ a: this.a, b: this.b, c: this.c });
|
|
@@ -66,7 +66,7 @@ class Cell {
|
|
|
66
66
|
isPointInsideCellCartesian(point) {
|
|
67
67
|
const { tolerance } = this.constructor;
|
|
68
68
|
return (this.convertPointToCrystal(point)
|
|
69
|
-
.map((c) =>
|
|
69
|
+
.map((c) => utils_1.Utils.math.isBetweenZeroInclusiveAndOne(c, tolerance))
|
|
70
70
|
// @ts-ignore
|
|
71
71
|
.reduce((a, b) => a && b));
|
|
72
72
|
}
|
|
@@ -74,7 +74,7 @@ class Cell {
|
|
|
74
74
|
isPointInsideCellCrystal(point) {
|
|
75
75
|
const { tolerance } = this.constructor;
|
|
76
76
|
return (point
|
|
77
|
-
.map((c) =>
|
|
77
|
+
.map((c) => utils_1.Utils.math.isBetweenZeroInclusiveAndOne(c, tolerance))
|
|
78
78
|
// @ts-ignore
|
|
79
79
|
.reduce((a, b) => a && b));
|
|
80
80
|
}
|
|
@@ -85,10 +85,11 @@ class Cell {
|
|
|
85
85
|
return this.isPointInsideCellCartesian(point);
|
|
86
86
|
}
|
|
87
87
|
getMostCollinearVectorIndex(testVector) {
|
|
88
|
-
const angles = this.vectorArrays.map((v) =>
|
|
89
|
-
return angles.findIndex((el) => el ===
|
|
88
|
+
const angles = this.vectorArrays.map((v) => utils_1.Utils.math.angleUpTo90(v, testVector, "deg"));
|
|
89
|
+
return angles.findIndex((el) => el === utils_1.Utils.math.min(angles));
|
|
90
90
|
}
|
|
91
91
|
scaleByMatrix(matrix) {
|
|
92
|
+
// @ts-ignore - mathjs v12 multiply return type is broader than runtime
|
|
92
93
|
[this.a, this.b, this.c] = MATRIX_MULT(matrix, this.vectorArrays);
|
|
93
94
|
}
|
|
94
95
|
toJSON() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getPrimitiveLatticeVectorsFromConfig = getPrimitiveLatticeVectorsFromConfig;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@mat3ra/utils");
|
|
5
5
|
/**
|
|
6
6
|
* Routines for calculating primitive cell vectors from conventional cell Bravais parameters.
|
|
7
7
|
* Following Setyawan, W., & Curtarolo, S. (2010). doi:10.1016/j.commatsci.2010.05.010
|
|
@@ -72,50 +72,49 @@ const PRIMITIVE_CELLS = {
|
|
|
72
72
|
},
|
|
73
73
|
HEX: ({ a, c }) => {
|
|
74
74
|
return [
|
|
75
|
-
[a / 2, (-a *
|
|
76
|
-
[a / 2, (a *
|
|
75
|
+
[a / 2, (-a * Number(utils_1.Utils.math.sqrt(3))) / 2, 0],
|
|
76
|
+
[a / 2, (a * Number(utils_1.Utils.math.sqrt(3))) / 2, 0],
|
|
77
77
|
[0, 0, c],
|
|
78
78
|
];
|
|
79
79
|
},
|
|
80
80
|
RHL: ({ a, alpha }) => {
|
|
81
|
-
const cosAlpha =
|
|
82
|
-
const cosHalfAlpha =
|
|
83
|
-
const sinHalfAlpha =
|
|
81
|
+
const cosAlpha = Number(utils_1.Utils.math.cos((alpha / 180) * Number(utils_1.Utils.math.PI)));
|
|
82
|
+
const cosHalfAlpha = Number(utils_1.Utils.math.sqrt((1 / 2) * (1 + cosAlpha)));
|
|
83
|
+
const sinHalfAlpha = Number(utils_1.Utils.math.sqrt((1 / 2) * (1 - cosAlpha)));
|
|
84
84
|
return [
|
|
85
85
|
[a * cosHalfAlpha, -a * sinHalfAlpha, 0.0],
|
|
86
86
|
[a * cosHalfAlpha, a * sinHalfAlpha, 0.0],
|
|
87
87
|
[
|
|
88
88
|
(a * cosAlpha) / cosHalfAlpha,
|
|
89
89
|
0.0,
|
|
90
|
-
a *
|
|
90
|
+
a *
|
|
91
|
+
Number(utils_1.Utils.math.sqrt(1 - (cosAlpha * cosAlpha) / (cosHalfAlpha * cosHalfAlpha))),
|
|
91
92
|
],
|
|
92
93
|
];
|
|
93
94
|
},
|
|
94
95
|
MCL: ({ a, b, c, alpha }) => {
|
|
95
|
-
const cosAlpha =
|
|
96
|
+
const cosAlpha = Number(utils_1.Utils.math.cos((alpha / 180) * Number(utils_1.Utils.math.PI)));
|
|
96
97
|
return [
|
|
97
98
|
[a, 0, 0],
|
|
98
99
|
[0, b, 0],
|
|
99
|
-
[0, c * cosAlpha, c *
|
|
100
|
+
[0, c * cosAlpha, c * Number(utils_1.Utils.math.sqrt(1 - cosAlpha * cosAlpha))],
|
|
100
101
|
];
|
|
101
102
|
},
|
|
102
103
|
MCLC: ({ a, b, c, alpha }) => {
|
|
103
|
-
const cosAlpha =
|
|
104
|
+
const cosAlpha = Number(utils_1.Utils.math.cos((alpha / 180) * Number(utils_1.Utils.math.PI)));
|
|
104
105
|
return [
|
|
105
106
|
[a / 2, b / 2, 0],
|
|
106
107
|
[-a / 2, b / 2, 0],
|
|
107
|
-
[0, c * cosAlpha, c *
|
|
108
|
+
[0, c * cosAlpha, c * Number(utils_1.Utils.math.sqrt(1 - cosAlpha * cosAlpha))],
|
|
108
109
|
];
|
|
109
110
|
},
|
|
110
111
|
// Algorithm from http://pymatgen.org/_modules/pymatgen/core/lattice.html (from_params)
|
|
111
112
|
TRI: ({ a, b, c, alpha, beta, gamma }) => {
|
|
112
113
|
// convert angles to Radians
|
|
113
114
|
// eslint-disable-next-line no-param-reassign
|
|
114
|
-
[alpha, beta, gamma] = [alpha, beta, gamma].map(
|
|
115
|
-
|
|
116
|
-
(x) =>
|
|
117
|
-
const [cosAlpha, cosBeta, cosGamma] = [alpha, beta, gamma].map((x) => math_1.math.cos(x));
|
|
118
|
-
const [sinAlpha, sinBeta] = [alpha, beta].map((x) => math_1.math.sin(x));
|
|
115
|
+
[alpha, beta, gamma] = [alpha, beta, gamma].map((x) => Number(utils_1.Utils.math.unit(x, "degree").to("rad").value));
|
|
116
|
+
const [cosAlpha, cosBeta, cosGamma] = [alpha, beta, gamma].map((x) => Number(utils_1.Utils.math.cos(x)));
|
|
117
|
+
const [sinAlpha, sinBeta] = [alpha, beta].map((x) => Number(utils_1.Utils.math.sin(x)));
|
|
119
118
|
let acosArg = (cosAlpha * cosBeta - cosGamma) / (sinAlpha * sinBeta);
|
|
120
119
|
if (acosArg < -1) {
|
|
121
120
|
acosArg = -1;
|
|
@@ -123,9 +122,9 @@ const PRIMITIVE_CELLS = {
|
|
|
123
122
|
else if (acosArg > 1) {
|
|
124
123
|
acosArg = 1;
|
|
125
124
|
}
|
|
126
|
-
const gammaStar =
|
|
127
|
-
const cosGammaStar =
|
|
128
|
-
const sinGammaStar =
|
|
125
|
+
const gammaStar = Number(utils_1.Utils.math.acos(acosArg));
|
|
126
|
+
const cosGammaStar = Number(utils_1.Utils.math.cos(gammaStar));
|
|
127
|
+
const sinGammaStar = Number(utils_1.Utils.math.sin(gammaStar));
|
|
129
128
|
return [
|
|
130
129
|
[a * sinBeta, 0.0, a * cosBeta],
|
|
131
130
|
[-b * sinAlpha * cosGammaStar, b * sinAlpha * sinGammaStar, b * cosAlpha],
|
|
@@ -34,14 +34,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Lattice = exports.LatticeVectors = exports.molecularLatticePaddingFactor = exports.diatomicLatticePaddingFactor = exports.defaultNonPeriodicMinimumLatticeSize = void 0;
|
|
37
|
-
const constants_1 = require("@mat3ra/code/dist/js/constants");
|
|
38
37
|
const entity_1 = require("@mat3ra/code/dist/js/entity");
|
|
39
|
-
const
|
|
38
|
+
const utils_1 = require("@mat3ra/utils");
|
|
40
39
|
const lodash = __importStar(require("lodash"));
|
|
41
40
|
const cell_1 = require("../cell/cell");
|
|
42
41
|
const primitive_cell_1 = require("../cell/primitive_cell");
|
|
43
42
|
const lattice_types_1 = require("./lattice_types");
|
|
44
43
|
const unit_cell_1 = require("./unit_cell");
|
|
44
|
+
const { HASH_TOLERANCE } = utils_1.Utils.constants;
|
|
45
45
|
/**
|
|
46
46
|
* Scaling factor used to calculate the new lattice size for non-periodic systems.
|
|
47
47
|
* The scaling factor ensures that a non-periodic structure will have have a lattice greater than the structures size.
|
|
@@ -79,17 +79,19 @@ class Lattice extends entity_1.InMemoryEntity {
|
|
|
79
79
|
const { a } = this;
|
|
80
80
|
const { b } = this;
|
|
81
81
|
const { c } = this;
|
|
82
|
-
const alphaRad =
|
|
83
|
-
const betaRad =
|
|
84
|
-
const gammaRad =
|
|
85
|
-
const cosAlpha =
|
|
86
|
-
const cosBeta =
|
|
87
|
-
const cosGamma =
|
|
88
|
-
const sinAlpha =
|
|
89
|
-
const sinBeta =
|
|
90
|
-
const gammaStar =
|
|
91
|
-
|
|
92
|
-
const
|
|
82
|
+
const alphaRad = utils_1.Utils.math.unit(this.alpha, "deg").toNumber("rad");
|
|
83
|
+
const betaRad = utils_1.Utils.math.unit(this.beta, "deg").toNumber("rad");
|
|
84
|
+
const gammaRad = utils_1.Utils.math.unit(this.gamma, "deg").toNumber("rad");
|
|
85
|
+
const cosAlpha = utils_1.Utils.math.cos(alphaRad);
|
|
86
|
+
const cosBeta = utils_1.Utils.math.cos(betaRad);
|
|
87
|
+
const cosGamma = utils_1.Utils.math.cos(gammaRad);
|
|
88
|
+
const sinAlpha = utils_1.Utils.math.sin(alphaRad);
|
|
89
|
+
const sinBeta = utils_1.Utils.math.sin(betaRad);
|
|
90
|
+
const gammaStar = utils_1.Utils.math.acos((cosAlpha * cosBeta - cosGamma) / (sinAlpha * sinBeta));
|
|
91
|
+
// @ts-ignore - mathjs v12 acos return type includes Complex, but inputs are always real
|
|
92
|
+
const cosGammaStar = utils_1.Utils.math.cos(gammaStar);
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
const sinGammaStar = utils_1.Utils.math.sin(gammaStar);
|
|
93
95
|
const vectorA = [a * sinBeta, 0.0, a * cosBeta];
|
|
94
96
|
const vectorB = [
|
|
95
97
|
-b * sinAlpha * cosGammaStar,
|
|
@@ -104,12 +106,12 @@ class Lattice extends entity_1.InMemoryEntity {
|
|
|
104
106
|
}
|
|
105
107
|
static fromVectorsArray(vectors, units = Lattice.defaultConfig.units, type = "TRI") {
|
|
106
108
|
const [aVec, bVec, cVec] = vectors;
|
|
107
|
-
const a =
|
|
108
|
-
const b =
|
|
109
|
-
const c =
|
|
110
|
-
const alpha =
|
|
111
|
-
const beta =
|
|
112
|
-
const gamma =
|
|
109
|
+
const a = utils_1.Utils.math.vlen(aVec);
|
|
110
|
+
const b = utils_1.Utils.math.vlen(bVec);
|
|
111
|
+
const c = utils_1.Utils.math.vlen(cVec);
|
|
112
|
+
const alpha = utils_1.Utils.math.angle(bVec, cVec, "deg");
|
|
113
|
+
const beta = utils_1.Utils.math.angle(aVec, cVec, "deg");
|
|
114
|
+
const gamma = utils_1.Utils.math.angle(aVec, bVec, "deg");
|
|
113
115
|
return new Lattice({
|
|
114
116
|
a,
|
|
115
117
|
b,
|
|
@@ -154,7 +156,7 @@ class Lattice extends entity_1.InMemoryEntity {
|
|
|
154
156
|
*/
|
|
155
157
|
get typeExtended() {
|
|
156
158
|
const { a, b, c, alpha, beta, gamma, type } = this;
|
|
157
|
-
const cosAlpha =
|
|
159
|
+
const cosAlpha = utils_1.Utils.math.cos((alpha / 180) * utils_1.Utils.math.PI);
|
|
158
160
|
switch (type) {
|
|
159
161
|
case "BCT":
|
|
160
162
|
return c < a ? "BCT-1" : "BCT-2";
|
|
@@ -189,14 +191,14 @@ class Lattice extends entity_1.InMemoryEntity {
|
|
|
189
191
|
* Calculate the volume of the lattice cell.
|
|
190
192
|
*/
|
|
191
193
|
get volume() {
|
|
192
|
-
return
|
|
194
|
+
return utils_1.Utils.math.abs(utils_1.Utils.math.det(this.vectorArrays));
|
|
193
195
|
}
|
|
194
196
|
/*
|
|
195
197
|
* Returns a "default" primitive lattice by type, with lattice parameters scaled by the length of "a",
|
|
196
198
|
* @param latticeConfig {Object} LatticeBravais config (see constructor)
|
|
197
199
|
*/
|
|
198
200
|
static getDefaultPrimitiveLatticeConfigByType(latticeConfig) {
|
|
199
|
-
const f_ =
|
|
201
|
+
const f_ = utils_1.Utils.math.roundArrayOrNumber;
|
|
200
202
|
// construct new primitive cell using lattice parameters and skip rounding the vectors
|
|
201
203
|
const vectors = (0, primitive_cell_1.getPrimitiveLatticeVectorsFromConfig)(latticeConfig);
|
|
202
204
|
// create new lattice from primitive cell
|
|
@@ -234,7 +236,7 @@ class Lattice extends entity_1.InMemoryEntity {
|
|
|
234
236
|
scaledLattice.beta,
|
|
235
237
|
scaledLattice.gamma,
|
|
236
238
|
]
|
|
237
|
-
.map((x) =>
|
|
239
|
+
.map((x) => utils_1.Utils.math.roundCustom(x, HASH_TOLERANCE))
|
|
238
240
|
.join(";")};`;
|
|
239
241
|
}
|
|
240
242
|
/**
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ReciprocalLattice = void 0;
|
|
7
7
|
const constants_1 = require("@mat3ra/code/dist/js/constants");
|
|
8
|
-
const
|
|
8
|
+
const utils_1 = require("@mat3ra/utils");
|
|
9
9
|
const lodash_1 = __importDefault(require("lodash"));
|
|
10
10
|
const lattice_1 = require("../lattice");
|
|
11
11
|
const paths_1 = require("./paths");
|
|
@@ -17,26 +17,26 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
17
17
|
*/
|
|
18
18
|
get reciprocalVectors() {
|
|
19
19
|
const vectors_ = this.vectors.vectorArrays;
|
|
20
|
-
const a =
|
|
21
|
-
const divider =
|
|
20
|
+
const a = utils_1.Utils.math.vlen(vectors_[0]);
|
|
21
|
+
const divider = utils_1.Utils.math.multiply(vectors_[0], utils_1.Utils.math.cross(vectors_[1], vectors_[2])) / a;
|
|
22
22
|
return [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
utils_1.Utils.math.multiply(utils_1.Utils.math.cross(vectors_[1], vectors_[2]), 1 / divider),
|
|
24
|
+
utils_1.Utils.math.multiply(utils_1.Utils.math.cross(vectors_[2], vectors_[0]), 1 / divider),
|
|
25
|
+
utils_1.Utils.math.multiply(utils_1.Utils.math.cross(vectors_[0], vectors_[1]), 1 / divider),
|
|
26
26
|
];
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Norms of reciprocal vectors.
|
|
30
30
|
*/
|
|
31
31
|
get reciprocalVectorNorms() {
|
|
32
|
-
return this.reciprocalVectors.map((vec) =>
|
|
32
|
+
return this.reciprocalVectors.map((vec) => utils_1.Utils.math.norm(vec));
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Ratio of reciprocal vector norms scaled by the inverse of the largest component.
|
|
36
36
|
*/
|
|
37
37
|
get reciprocalVectorRatios() {
|
|
38
38
|
const norms = this.reciprocalVectorNorms;
|
|
39
|
-
const maxNorm =
|
|
39
|
+
const maxNorm = utils_1.Utils.math.max(...norms);
|
|
40
40
|
return norms.map((n) => n / maxNorm);
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
@@ -45,7 +45,7 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
45
45
|
* @return {KPointCoordinates}
|
|
46
46
|
*/
|
|
47
47
|
getCartesianCoordinates(point) {
|
|
48
|
-
return
|
|
48
|
+
return utils_1.Utils.math.multiply(point, this.reciprocalVectors);
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
51
|
* Get the list of high-symmetry points for the current lattice.
|
|
@@ -72,7 +72,7 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
72
72
|
const symmPoints = this.symmetryPoints;
|
|
73
73
|
dataPoints.forEach((point, index) => {
|
|
74
74
|
const symmPoint = symmPoints.find((x) => {
|
|
75
|
-
return
|
|
75
|
+
return utils_1.Utils.math.vEqualWithTolerance(x.coordinates, point, 1e-4);
|
|
76
76
|
});
|
|
77
77
|
if (symmPoint) {
|
|
78
78
|
kpointPath.push({
|
|
@@ -94,8 +94,8 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
94
94
|
calculateDimension(nPoints, index) {
|
|
95
95
|
const norms = this.reciprocalVectorNorms;
|
|
96
96
|
const [j, k] = [0, 1, 2].filter((i) => i !== index); // get indices of other two dimensions
|
|
97
|
-
const N =
|
|
98
|
-
return
|
|
97
|
+
const N = utils_1.Utils.math.cbrt((nPoints * norms[index] ** 2) / (norms[j] * norms[k]));
|
|
98
|
+
return utils_1.Utils.math.max(1, utils_1.Utils.math.ceil(N));
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* Calculate grid dimensions from total number of k-points.
|
|
@@ -110,10 +110,10 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
110
110
|
const { a } = this;
|
|
111
111
|
return {
|
|
112
112
|
[constants_1.ATOMIC_COORD_UNITS.cartesian]: {
|
|
113
|
-
[constants_1.units.angstrom]: (2 *
|
|
113
|
+
[constants_1.units.angstrom]: (2 * utils_1.Utils.math.PI) / a,
|
|
114
114
|
},
|
|
115
115
|
[constants_1.units.angstrom]: {
|
|
116
|
-
[constants_1.ATOMIC_COORD_UNITS.cartesian]: a / (2 *
|
|
116
|
+
[constants_1.ATOMIC_COORD_UNITS.cartesian]: a / (2 * utils_1.Utils.math.PI),
|
|
117
117
|
},
|
|
118
118
|
};
|
|
119
119
|
}
|
|
@@ -127,7 +127,7 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
127
127
|
getDimensionsFromSpacing(spacing, units = constants_1.ATOMIC_COORD_UNITS.cartesian) {
|
|
128
128
|
const factor = this.conversionTable[units][constants_1.ATOMIC_COORD_UNITS.cartesian] || 1;
|
|
129
129
|
return this.reciprocalVectorNorms.map((norm) => {
|
|
130
|
-
return
|
|
130
|
+
return utils_1.Utils.math.max(1, utils_1.Utils.math.ceil(lodash_1.default.round(norm / (spacing * factor), 4)));
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
@@ -140,7 +140,7 @@ class ReciprocalLattice extends lattice_1.Lattice {
|
|
|
140
140
|
const factor = this.conversionTable[constants_1.ATOMIC_COORD_UNITS.cartesian][units] || 1;
|
|
141
141
|
const norms = this.reciprocalVectorNorms;
|
|
142
142
|
return (factor *
|
|
143
|
-
|
|
143
|
+
utils_1.Utils.math.mean(dimensions.map((dim, i) => norms[i] / utils_1.Utils.math.max(1, dim))));
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
exports.ReciprocalLattice = ReciprocalLattice;
|
|
@@ -4,14 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.atomsCount = atomsCount;
|
|
7
|
-
const math_1 = require("@mat3ra/code/dist/js/math");
|
|
8
7
|
const utils_1 = require("@mat3ra/utils");
|
|
9
8
|
const underscore_string_1 = __importDefault(require("underscore.string"));
|
|
10
9
|
const constrained_basis_1 = require("../basis/constrained_basis");
|
|
11
10
|
const cell_1 = require("../cell/cell");
|
|
12
11
|
const constants_1 = require("../constants");
|
|
13
12
|
const lattice_1 = require("../lattice/lattice");
|
|
14
|
-
const _print = (x, printFormat = "%14.9f") => underscore_string_1.default.sprintf(printFormat,
|
|
13
|
+
const _print = (x, printFormat = "%14.9f") => underscore_string_1.default.sprintf(printFormat, utils_1.Utils.math.precise(x));
|
|
15
14
|
const _latticeVectorsToString = (vectors) => vectors.map((v) => v.map((c) => _print(c)).join("\t")).join("\n");
|
|
16
15
|
const atomicConstraintsCharFromBool = (bool) => (bool ? "T" : "F");
|
|
17
16
|
/**
|
|
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.CombinatorialBasis = exports.WrongBasisFormat = void 0;
|
|
37
|
-
const
|
|
37
|
+
const utils_1 = require("@mat3ra/utils");
|
|
38
38
|
const lodash_1 = require("lodash");
|
|
39
39
|
const s = __importStar(require("underscore.string"));
|
|
40
40
|
const cell_1 = require("../cell/cell");
|
|
@@ -209,7 +209,7 @@ class CombinatorialBasis {
|
|
|
209
209
|
dimensions.push(itemsSet);
|
|
210
210
|
});
|
|
211
211
|
// @ts-ignore // We're multiplying objects with math, not numbers. No type casting will help.
|
|
212
|
-
const basisSet =
|
|
212
|
+
const basisSet = utils_1.Utils.math.cartesianProduct.apply(null, dimensions);
|
|
213
213
|
return basisSet.map((basis) => basis.filter((entry) => entry.element !== VACANCY_CHARACTER));
|
|
214
214
|
}
|
|
215
215
|
/**
|
package/dist/js/tools/basis.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const utils_1 = require("@mat3ra/utils");
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
5
|
const coordinates_1 = require("../basis/coordinates");
|
|
6
|
-
const ADD =
|
|
7
|
-
const MULT =
|
|
6
|
+
const ADD = utils_1.Utils.math.add;
|
|
7
|
+
const MULT = utils_1.Utils.math.multiply;
|
|
8
8
|
/**
|
|
9
9
|
* Returns a repeated basis of a crystal.
|
|
10
10
|
* @param basis {Basis} Original basis.
|
package/dist/js/tools/cell.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const utils_1 = require("@mat3ra/utils");
|
|
4
4
|
const cell_1 = require("../cell/cell");
|
|
5
5
|
/**
|
|
6
6
|
* Returns the list of points on the original lattice contained in the supercell in fractional coordinates.
|
|
@@ -19,8 +19,8 @@ function latticePointsInSupercell(supercellMatrix) {
|
|
|
19
19
|
[1, 1, 1],
|
|
20
20
|
];
|
|
21
21
|
const d_points = diagonals.map((point) => supercell.convertPointToCartesian(point));
|
|
22
|
-
const mins = [0, 1, 2].map((i) =>
|
|
23
|
-
const maxes = [0, 1, 2].map((i) =>
|
|
22
|
+
const mins = [0, 1, 2].map((i) => utils_1.Utils.math.min(...d_points.map((p) => p[i])));
|
|
23
|
+
const maxes = [0, 1, 2].map((i) => utils_1.Utils.math.max(...d_points.map((p) => p[i])) + 1);
|
|
24
24
|
const points = [];
|
|
25
25
|
for (let i = mins[0]; i <= maxes[0]; i++) {
|
|
26
26
|
for (let j = mins[1]; j <= maxes[1]; j++) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const utils_1 = require("@mat3ra/utils");
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const lattice_1 = require("../lattice/lattice");
|
|
6
6
|
/**
|
|
@@ -38,8 +38,8 @@ function translateAtomsToCenter(material) {
|
|
|
38
38
|
material.toCartesian();
|
|
39
39
|
const updatedBasis = material.Basis;
|
|
40
40
|
const centerOfCoordinates = updatedBasis.centerOfCoordinatesPoint;
|
|
41
|
-
const centerOfLattice =
|
|
42
|
-
const translationVector =
|
|
41
|
+
const centerOfLattice = utils_1.Utils.math.multiply(0.5, material.Lattice.vectorArrays.reduce((a, b) => utils_1.Utils.math.add(a, b)));
|
|
42
|
+
const translationVector = utils_1.Utils.math.subtract(centerOfLattice, centerOfCoordinates);
|
|
43
43
|
updatedBasis.translateByVector(translationVector);
|
|
44
44
|
material.setBasis(updatedBasis.toJSON());
|
|
45
45
|
if (originalUnits !== constants_1.ATOMIC_COORD_UNITS.cartesian)
|
|
@@ -3,10 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
6
|
+
const utils_1 = require("@mat3ra/utils");
|
|
7
7
|
const lattice_1 = require("../lattice/lattice");
|
|
8
8
|
const cell_1 = __importDefault(require("./cell"));
|
|
9
|
-
const ADD =
|
|
9
|
+
const ADD = utils_1.Utils.math.add;
|
|
10
10
|
/**
|
|
11
11
|
* @summary Generates new basis for a supercell. For each site from basis generates shifts that are within supercell.
|
|
12
12
|
*/
|
|
@@ -39,7 +39,7 @@ function generateNewBasisWithinSupercell(basis, cell, supercell, supercellMatrix
|
|
|
39
39
|
* @param supercellMatrix {Number[][]}
|
|
40
40
|
*/
|
|
41
41
|
function generateConfig(material, supercellMatrix) {
|
|
42
|
-
const det =
|
|
42
|
+
const det = utils_1.Utils.math.det(supercellMatrix);
|
|
43
43
|
if (det === 0) {
|
|
44
44
|
throw new Error("Scaling matrix is degenerate.");
|
|
45
45
|
}
|
package/dist/js/tools/surface.js
CHANGED
|
@@ -3,14 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
6
|
+
const utils_1 = require("@mat3ra/utils");
|
|
7
7
|
const lattice_1 = require("../lattice/lattice");
|
|
8
8
|
const supercell_1 = __importDefault(require("./supercell"));
|
|
9
|
-
const MULT =
|
|
10
|
-
const ADD =
|
|
11
|
-
const DOT =
|
|
9
|
+
const MULT = utils_1.Utils.math.multiply;
|
|
10
|
+
const ADD = utils_1.Utils.math.add;
|
|
11
|
+
const DOT = utils_1.Utils.math.product;
|
|
12
12
|
const getMatrixInLeftHandedRepresentation = (matrix) => {
|
|
13
|
-
return
|
|
13
|
+
return utils_1.Utils.math.det(matrix) < 0 ? MULT(matrix, -1) : matrix;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* Helper function for extended GCD.
|
|
@@ -22,10 +22,10 @@ const getMatrixInLeftHandedRepresentation = (matrix) => {
|
|
|
22
22
|
function extGCD(a, b) {
|
|
23
23
|
if (b === 0)
|
|
24
24
|
return [1, 0];
|
|
25
|
-
if (
|
|
25
|
+
if (utils_1.Utils.math.mod(a, b) === 0)
|
|
26
26
|
return [0, 1];
|
|
27
|
-
const [x, y] = extGCD(b,
|
|
28
|
-
return [y, x - y *
|
|
27
|
+
const [x, y] = extGCD(b, utils_1.Utils.math.mod(a, b));
|
|
28
|
+
return [y, x - y * utils_1.Utils.math.floor(a / b)];
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Generates a slab scaling matrix for the specified cell based on miller indices.
|
|
@@ -36,7 +36,7 @@ function extGCD(a, b) {
|
|
|
36
36
|
* @return {Number[][]}
|
|
37
37
|
*/
|
|
38
38
|
function getMillerScalingMatrix(cell, millerIndices, tol = 1e-8) {
|
|
39
|
-
if (!millerIndices.reduce((a, b) =>
|
|
39
|
+
if (!millerIndices.reduce((a, b) => utils_1.Utils.math.abs(a) + utils_1.Utils.math.abs(b)))
|
|
40
40
|
throw new Error("Miller indices are zeros.");
|
|
41
41
|
let scalingMatrix;
|
|
42
42
|
const [h, k, l] = millerIndices;
|
|
@@ -78,19 +78,21 @@ function getMillerScalingMatrix(cell, millerIndices, tol = 1e-8) {
|
|
|
78
78
|
const k1 = DOT(ADD(MULT(p, z1), MULT(q, z2)), z3);
|
|
79
79
|
// @ts-ignore
|
|
80
80
|
const k2 = DOT(ADD(MULT(l, z1), -MULT(k, z2)), z3);
|
|
81
|
-
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
if (utils_1.Utils.math.abs(k2) > tol) {
|
|
82
83
|
// For mathjs version 3.20: round(-0.5) = -0
|
|
83
84
|
// For mathjs version 5.10: round(-0.5) = -1
|
|
84
85
|
// Here we specify rounding method to Bankers
|
|
85
86
|
// For Python 3.11: round(-0.5) = 0
|
|
87
|
+
// @ts-ignore - mathjs v12 dot return type
|
|
86
88
|
const value = k1 / k2;
|
|
87
|
-
const roundedValue =
|
|
89
|
+
const roundedValue = utils_1.Utils.math.roundCustom(value, 0, utils_1.Utils.math.RoundingMethod.Bankers);
|
|
88
90
|
const i = -roundedValue;
|
|
89
91
|
[p, q] = [p + i * l, q - i * k];
|
|
90
92
|
}
|
|
91
93
|
const [a, b] = extGCD(p * k + q * l, h);
|
|
92
94
|
const c1 = [p * k + q * l, -p * h, -q * h];
|
|
93
|
-
const c2 = [0, l, -k].map((c) =>
|
|
95
|
+
const c2 = [0, l, -k].map((c) => utils_1.Utils.math.trunc(c / utils_1.Utils.math.gcd(l, k))); // floor division
|
|
94
96
|
const c3 = [b, a * p, a * q];
|
|
95
97
|
scalingMatrix = [c1, c2, c3];
|
|
96
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mat3ra/made",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.13-0",
|
|
4
4
|
"description": "MAterials DEsign library",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "eslint --cache src/js tests/js && prettier --write src/js tests/js",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"@mat3ra/code": "^2026.5.27-0",
|
|
38
38
|
"@mat3ra/esse": "^2026.6.30-0",
|
|
39
39
|
"@mat3ra/tsconfig": "^2024.6.3-0",
|
|
40
|
-
"@mat3ra/utils": "^2026.7.
|
|
40
|
+
"@mat3ra/utils": "^2026.7.8-0",
|
|
41
|
+
"@mat3ra/standata": "2026.6.30-0",
|
|
41
42
|
"@types/crypto-js": "^4.2.2",
|
|
42
43
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
43
44
|
"@typescript-eslint/parser": "^5.62.0",
|