@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,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const lattice_bravais_1 = require("../lattice/lattice_bravais");
|
|
7
|
+
const math_1 = __importDefault(require("../math"));
|
|
8
|
+
const supercell_1 = __importDefault(require("./supercell"));
|
|
9
|
+
const MULT = math_1.default.multiply;
|
|
10
|
+
const ADD = math_1.default.add;
|
|
11
|
+
const DOT = math_1.default.product;
|
|
12
|
+
const getMatrixInLeftHandedRepresentation = (matrix) => {
|
|
13
|
+
return math_1.default.det(matrix) < 0 ? MULT(matrix, -1) : matrix;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Helper function for extended GCD.
|
|
17
|
+
* Inspired by https://gitlab.com/ase/ase/blob/master/ase/build/general_surface.py
|
|
18
|
+
* @param {Number} a
|
|
19
|
+
* @param {Number} b
|
|
20
|
+
* @return {Array}
|
|
21
|
+
*/
|
|
22
|
+
function extGCD(a, b) {
|
|
23
|
+
if (b === 0)
|
|
24
|
+
return [1, 0];
|
|
25
|
+
if (math_1.default.mod(a, b) === 0)
|
|
26
|
+
return [0, 1];
|
|
27
|
+
const [x, y] = extGCD(b, math_1.default.mod(a, b));
|
|
28
|
+
return [y, x - y * math_1.default.floor(a, b)];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generates a slab scaling matrix for the specified cell based on miller indices.
|
|
32
|
+
* Inspired by from https://gitlab.com/ase/ase/blob/master/ase/build/general_surface.py.
|
|
33
|
+
* @param cell {Cell}
|
|
34
|
+
* @param millerIndices {Number[]}
|
|
35
|
+
* @param tol {Number} Zero-value tolerance
|
|
36
|
+
* @return {Number[][]}
|
|
37
|
+
*/
|
|
38
|
+
function getMillerScalingMatrix(cell, millerIndices, tol = 1e-8) {
|
|
39
|
+
if (!millerIndices.reduce((a, b) => math_1.default.abs(a) + math_1.default.abs(b)))
|
|
40
|
+
throw new Error("Miller indices are zeros.");
|
|
41
|
+
let scalingMatrix;
|
|
42
|
+
const [h, k, l] = millerIndices;
|
|
43
|
+
const [h0, k0, l0] = millerIndices.map((i) => i === 0);
|
|
44
|
+
if ((h0 && k0) || (h0 && l0) || (k0 && l0)) {
|
|
45
|
+
// if any two indices are zero
|
|
46
|
+
if (!h0) {
|
|
47
|
+
scalingMatrix = [
|
|
48
|
+
[0, 1, 0],
|
|
49
|
+
[0, 0, 1],
|
|
50
|
+
[1, 0, 0],
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
if (!k0) {
|
|
54
|
+
scalingMatrix = [
|
|
55
|
+
[0, 0, 1],
|
|
56
|
+
[1, 0, 0],
|
|
57
|
+
[0, 1, 0],
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
if (!l0) {
|
|
61
|
+
scalingMatrix = [
|
|
62
|
+
[1, 0, 0],
|
|
63
|
+
[0, 1, 0],
|
|
64
|
+
[0, 0, 1],
|
|
65
|
+
];
|
|
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
|
+
let [p, q] = extGCD(k, l);
|
|
77
|
+
const k1 = DOT(ADD(MULT(p, z1), MULT(q, z2)), z3);
|
|
78
|
+
const k2 = DOT(ADD(MULT(l, z1), MULT(-1, k, z2)), z3);
|
|
79
|
+
if (math_1.default.abs(k2) > tol) {
|
|
80
|
+
const i = -parseInt(math_1.default.round(k1 / k2), 10);
|
|
81
|
+
[p, q] = [p + i * l, q - i * k];
|
|
82
|
+
}
|
|
83
|
+
const [a, b] = extGCD(p * k + q * l, h);
|
|
84
|
+
const c1 = [p * k + q * l, -p * h, -q * h];
|
|
85
|
+
const c2 = [0, l, -k].map((c) => math_1.default.trunc(c / math_1.default.gcd(l, k))); // floor division
|
|
86
|
+
const c3 = [b, a * p, a * q];
|
|
87
|
+
scalingMatrix = [c1, c2, c3];
|
|
88
|
+
}
|
|
89
|
+
return getMatrixInLeftHandedRepresentation(scalingMatrix);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Scale the surface cell in out-of-plane direction according to thickness
|
|
93
|
+
* and construct the lateral supercell from vx/vy parameters.
|
|
94
|
+
* @param bulkCell {Cell}
|
|
95
|
+
* @param surfaceCell {Cell}
|
|
96
|
+
* @param outOfPlaneAxisIndex {Number} Index of the cell vector most collinear with the out-of-surface-plane vector
|
|
97
|
+
* @param thickness {Number} Surface (Slab) thickness in layers (Positive Integer).
|
|
98
|
+
* @param vx {Number} Size of lateral supercell along the direction of the first (x) cell vector (Positive Integer).
|
|
99
|
+
* @param vy {Number} Size of lateral supercell along the direction of the second (y) cell vector (Positive Integer).
|
|
100
|
+
* @return {Number[][]}
|
|
101
|
+
*/
|
|
102
|
+
function getDimensionsScalingMatrix(bulkCell, surfaceCell, outOfPlaneAxisIndex, thickness, vx, vy) {
|
|
103
|
+
const transformationMatrix = math_1.default.eye(3).toArray();
|
|
104
|
+
const vxIndex = outOfPlaneAxisIndex === 2 ? 0 : outOfPlaneAxisIndex + 1;
|
|
105
|
+
const vyIndex = vxIndex === 2 ? 0 : vxIndex + 1;
|
|
106
|
+
transformationMatrix[outOfPlaneAxisIndex] = MULT(thickness, transformationMatrix[outOfPlaneAxisIndex]);
|
|
107
|
+
transformationMatrix[vxIndex] = MULT(vx, transformationMatrix[vxIndex]);
|
|
108
|
+
transformationMatrix[vyIndex] = MULT(vy, transformationMatrix[vyIndex]);
|
|
109
|
+
return transformationMatrix;
|
|
110
|
+
}
|
|
111
|
+
/*
|
|
112
|
+
* Generate a config object for a surface based on a set of parameters.
|
|
113
|
+
* @param material {Material} The parent material (bulk) this surface is constructed from
|
|
114
|
+
* @param millerIndices {Number[]} Miller Indices that define the surface cleavage.
|
|
115
|
+
* @param numberOfLayers {Number} Surface (Slab) thickness in layers (Positive Integer).
|
|
116
|
+
* @param vx {Number} Size of lateral supercell along the direction of the first (x) cell vector (Positive Integer).
|
|
117
|
+
* @param vy {Number} Size of lateral supercell along the direction of the second (y) cell vector (Positive Integer).
|
|
118
|
+
* @return {Object}
|
|
119
|
+
*/
|
|
120
|
+
function generateConfig(material, millerIndices, numberOfLayers = 1, vx = 1, vy = 1) {
|
|
121
|
+
if (numberOfLayers < 1)
|
|
122
|
+
throw new Error("Made.tools.surface.generateConfig: number of layers < 1.");
|
|
123
|
+
const cell = material.Lattice.Cell;
|
|
124
|
+
const millerScalingMatrix = getMillerScalingMatrix(cell, millerIndices);
|
|
125
|
+
const millerSupercell = cell.cloneAndScaleByMatrix(millerScalingMatrix);
|
|
126
|
+
const millerPlanePseudoNormal = cell.convertPointToCartesian(millerIndices);
|
|
127
|
+
const outOfPlaneAxisIndex = millerSupercell.getMostCollinearVectorIndex(millerPlanePseudoNormal);
|
|
128
|
+
const dimensionsScalingMatrix = getDimensionsScalingMatrix(cell, millerSupercell, outOfPlaneAxisIndex, numberOfLayers, vx, vy);
|
|
129
|
+
const supercellMatrix = MULT(dimensionsScalingMatrix, millerScalingMatrix);
|
|
130
|
+
const supercell = millerSupercell.cloneAndScaleByMatrix(dimensionsScalingMatrix);
|
|
131
|
+
const newBasis = supercell_1.default.generateNewBasisWithinSupercell(material.Basis, cell, supercell, supercellMatrix);
|
|
132
|
+
const newLattice = lattice_bravais_1.LatticeBravais.fromVectors({
|
|
133
|
+
a: supercell.vector1,
|
|
134
|
+
b: supercell.vector2,
|
|
135
|
+
c: supercell.vector3,
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
name: `${material.name} - slab ${JSON.stringify(millerIndices)}`,
|
|
139
|
+
basis: newBasis.toJSON(),
|
|
140
|
+
lattice: newLattice.toJSON(),
|
|
141
|
+
// extra parameter for use in creating vacuum etc.
|
|
142
|
+
outOfPlaneAxisIndex,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
exports.default = {
|
|
146
|
+
generateConfig,
|
|
147
|
+
};
|
package/dist/types.d.ts
ADDED
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mat3ra/made",
|
|
3
|
+
"version": "2024.3.22-0",
|
|
4
|
+
"description": "MAterials DEsign library",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"lint": "eslint --cache src/js tests/js && prettier --write src/js tests/js",
|
|
7
|
+
"lint:fix": "eslint --fix --cache src/js tests/js && prettier --write src/js tests/js",
|
|
8
|
+
"lint:staged": "lint-staged",
|
|
9
|
+
"postinstall": "npm run transpile",
|
|
10
|
+
"prepare": "husky install",
|
|
11
|
+
"prettier": "prettier --check src/js tests/js",
|
|
12
|
+
"test": "nyc --reporter=text mocha --recursive --bail tests/js",
|
|
13
|
+
"transpile": "tsc"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/Exabyte-io/made.git"
|
|
18
|
+
},
|
|
19
|
+
"main": "dist/made.js",
|
|
20
|
+
"author": "Exabyte Inc.",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/Exabyte-io/made/issues"
|
|
23
|
+
},
|
|
24
|
+
"license": "Apache-2.0",
|
|
25
|
+
"homepage": "https://github.com/Exabyte-io/made",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=0.14"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@babel/eslint-parser": "^7.16.3",
|
|
31
|
+
"@babel/plugin-proposal-class-properties": "^7.16.0",
|
|
32
|
+
"@babel/preset-env": "^7.16.4",
|
|
33
|
+
"@babel/preset-react": "^7.16.7",
|
|
34
|
+
"@babel/register": "^7.22.15",
|
|
35
|
+
"@babel/runtime-corejs3": "^7.16.8",
|
|
36
|
+
"@exabyte-io/code.js": "2024.2.29-0",
|
|
37
|
+
"@exabyte-io/eslint-config": "^2023.8.29-1",
|
|
38
|
+
"@mat3ra/esse": "2024.3.20-0",
|
|
39
|
+
"@mat3ra/tsconfig": "^2024.3.21-5",
|
|
40
|
+
"@types/crypto-js": "^4.2.2",
|
|
41
|
+
"@types/mathjs": "^3.21.1",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^5.9.1",
|
|
43
|
+
"@typescript-eslint/parser": "^5.9.1",
|
|
44
|
+
"chai": "^4.3.4",
|
|
45
|
+
"chai-almost": "^1.0.1",
|
|
46
|
+
"eslint": "^7.32.0",
|
|
47
|
+
"eslint-config-airbnb": "^19.0.2",
|
|
48
|
+
"eslint-config-prettier": "^8.5.0",
|
|
49
|
+
"eslint-import-resolver-exports": "^1.0.0-beta.5",
|
|
50
|
+
"eslint-import-resolver-meteor": "^0.4.0",
|
|
51
|
+
"eslint-import-resolver-node": "^0.3.9",
|
|
52
|
+
"eslint-plugin-import": "^2.25.3",
|
|
53
|
+
"eslint-plugin-jsdoc": "^37.1.0",
|
|
54
|
+
"eslint-plugin-jsx-a11y": "^6.5.1",
|
|
55
|
+
"eslint-plugin-mui-path-imports": "0.0.15",
|
|
56
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
57
|
+
"eslint-plugin-react": "^7.30.0",
|
|
58
|
+
"eslint-plugin-simple-import-sort": "^7.0.0",
|
|
59
|
+
"husky": "^7.0.4",
|
|
60
|
+
"lint-staged": "^12.1.2",
|
|
61
|
+
"mocha": "10.3.0",
|
|
62
|
+
"prettier": "^2.5.1",
|
|
63
|
+
"nyc": "^15.1.0"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@babel/core": "7.24.1",
|
|
67
|
+
"@exabyte-io/periodic-table.js": "2022.5.28-0",
|
|
68
|
+
"@types/chai": "^4.3.5",
|
|
69
|
+
"@types/mocha": "^10.0.1",
|
|
70
|
+
"@types/node": "^20.4.2",
|
|
71
|
+
"@types/underscore": "^1.11.6",
|
|
72
|
+
"@types/underscore.string": "^0.0.40",
|
|
73
|
+
"array-almost-equal": "^1.0.0",
|
|
74
|
+
"crypto-js": "4.2.0",
|
|
75
|
+
"lodash": "^4.17.*",
|
|
76
|
+
"mathjs": "12.4.1",
|
|
77
|
+
"typescript": "^4.5.5",
|
|
78
|
+
"underscore": "^1.8.3",
|
|
79
|
+
"underscore.string": "^3.3.4"
|
|
80
|
+
},
|
|
81
|
+
"peerDependencies": {
|
|
82
|
+
"@exabyte-io/code.js": "*",
|
|
83
|
+
"@mat3ra/esse": "*"
|
|
84
|
+
},
|
|
85
|
+
"lint-staged": {
|
|
86
|
+
"*.js": "eslint --cache --fix",
|
|
87
|
+
"*.{js,css}": "prettier --write"
|
|
88
|
+
}
|
|
89
|
+
}
|
package/pyproject.toml
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mat3ra-made"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "MAterials DEfinitions and/or MAterials DEsign library."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
license = {file = "LICENSE.md"}
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Exabyte Inc.", email = "info@mat3ra.com"}
|
|
10
|
+
]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Programming Language :: Python",
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Topic :: Software Development",
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
# add requirements here
|
|
19
|
+
"numpy"
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
tests = [
|
|
24
|
+
"coverage[toml]>=5.3",
|
|
25
|
+
"pre-commit",
|
|
26
|
+
"black",
|
|
27
|
+
"ruff",
|
|
28
|
+
"isort",
|
|
29
|
+
"mypy",
|
|
30
|
+
"pip-tools"
|
|
31
|
+
]
|
|
32
|
+
all = ["mat3ra-made[tests]"]
|
|
33
|
+
|
|
34
|
+
# Entrypoint scripts can be defined here, see examples below.
|
|
35
|
+
[project.scripts]
|
|
36
|
+
# my-script = "my_package.my_module:my_function"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = [
|
|
41
|
+
"setuptools>=42",
|
|
42
|
+
"setuptools-scm[toml]>=3.4"
|
|
43
|
+
]
|
|
44
|
+
build-backend = "setuptools.build_meta"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools_scm]
|
|
47
|
+
git_describe_command = "git describe --tags --long"
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.packages.find]
|
|
50
|
+
where = ["src/py"]
|
|
51
|
+
|
|
52
|
+
[tool.black]
|
|
53
|
+
line-length = 120
|
|
54
|
+
target-version = ['py38']
|
|
55
|
+
# 'extend-exclude' excludes files or directories in addition to the defaults
|
|
56
|
+
extend-exclude = '''
|
|
57
|
+
(
|
|
58
|
+
examples\/.*\/.*\.py
|
|
59
|
+
| other\/.*\/.*\.(py|ipynb)
|
|
60
|
+
)
|
|
61
|
+
'''
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
# Exclude a variety of commonly ignored directories.
|
|
65
|
+
extend-exclude = [
|
|
66
|
+
"src/js"
|
|
67
|
+
]
|
|
68
|
+
line-length = 120
|
|
69
|
+
target-version = "py38"
|
|
70
|
+
|
|
71
|
+
[tool.ruff.per-file-ignores]
|
|
72
|
+
"__init__.py" = ["F401"]
|
|
73
|
+
|
|
74
|
+
[tool.isort]
|
|
75
|
+
profile = "black"
|
|
76
|
+
multi_line_output = 3
|
|
77
|
+
include_trailing_comma = true
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import _ from "underscore";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
isObjectWithIdAndValue,
|
|
5
|
+
ObjectWithIdAndValue,
|
|
6
|
+
ScalarWithId,
|
|
7
|
+
ValueOrObject,
|
|
8
|
+
} from "./scalar_with_id";
|
|
9
|
+
|
|
10
|
+
type Predicate<T> = (o: T) => boolean;
|
|
11
|
+
|
|
12
|
+
type MapFunction<T> = (value: T, index: number, array: T[]) => T;
|
|
13
|
+
|
|
14
|
+
export function isArrayOfObjectsWithIdAndValue<T>(
|
|
15
|
+
valueOrObjects: ValueOrObject<T>[],
|
|
16
|
+
): valueOrObjects is ObjectWithIdAndValue<T>[] {
|
|
17
|
+
return isObjectWithIdAndValue(valueOrObjects[0]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Helper class representing an ArrayWithIds. Used to explicitly track values assigned to atoms, for example.
|
|
22
|
+
*/
|
|
23
|
+
export class ArrayWithIds<T> {
|
|
24
|
+
array: T[];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create a an array with ids.
|
|
28
|
+
* @param {Array} array - Either regular array or ArrayWithIds (see @example above)
|
|
29
|
+
*/
|
|
30
|
+
constructor(array: ObjectWithIdAndValue<T>[] | T[] = []) {
|
|
31
|
+
if (!_.isArray(array)) {
|
|
32
|
+
throw new Error("ArrayWithIds.constructor: pass array on initialization");
|
|
33
|
+
}
|
|
34
|
+
// if passed an array with ids as config, only store the values in array
|
|
35
|
+
if (isArrayOfObjectsWithIdAndValue<T>(array)) {
|
|
36
|
+
this.array = array.sort((a, b) => a.id - b.id).map((element) => element.value);
|
|
37
|
+
} else {
|
|
38
|
+
this.array = [...array];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Serialize class instance to JSON.
|
|
44
|
+
* @example [{"id" : 0, "value" : "Si" }, {"id" : 1, "value" : "Si" }]
|
|
45
|
+
*/
|
|
46
|
+
toJSON(): ObjectWithIdAndValue<T>[] {
|
|
47
|
+
// from ["a", "b"] to [{id: 0, value: "a"}, {id: 1, value: "b"}]
|
|
48
|
+
return this.array.map((el, idx) => new ScalarWithId<T>(el, idx).toJSON());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Apply function fn to each element of the array and replace `array` with the result.
|
|
53
|
+
* @param fn - The function to be applied to each array element.
|
|
54
|
+
*/
|
|
55
|
+
mapArrayInPlace(fn: MapFunction<T>) {
|
|
56
|
+
if (!_.isFunction(fn)) {
|
|
57
|
+
throw new Error("ArrayWithIds.mapArray: must pass function as argument");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.array = this.array.map(fn);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getArrayElementByIndex(idx: number) {
|
|
64
|
+
return this.array[idx];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the index of the array element that passes the predicate.
|
|
69
|
+
* @param {Function} predicate - The function to be applied to each array element.
|
|
70
|
+
*/
|
|
71
|
+
getArrayIndexByPredicate(predicate: Predicate<T>) {
|
|
72
|
+
return this.array.findIndex((el) => predicate(el));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Add an entity to array.
|
|
77
|
+
* @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
|
|
78
|
+
*/
|
|
79
|
+
addElement(el: ValueOrObject<T>) {
|
|
80
|
+
const value = isObjectWithIdAndValue(el) ? el.value : el;
|
|
81
|
+
if (el) this.array.push(value);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Remove an entity to array. Either by passing the entity, or the corresponding index.
|
|
86
|
+
* @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
|
|
87
|
+
* @param idx - The entity to be added to array. If Object with 'value' key, its value will be added.
|
|
88
|
+
*/
|
|
89
|
+
removeElement(el: ValueOrObject<T> | null, idx?: number) {
|
|
90
|
+
let _idx;
|
|
91
|
+
if (idx === undefined) {
|
|
92
|
+
_idx = this.array.findIndex((elm) => elm === el);
|
|
93
|
+
} else {
|
|
94
|
+
_idx = idx;
|
|
95
|
+
}
|
|
96
|
+
if (_idx !== undefined) {
|
|
97
|
+
this.array.splice(_idx, 1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import _ from "underscore";
|
|
2
|
+
|
|
3
|
+
export interface ObjectWithIdAndValue<T> {
|
|
4
|
+
id: number;
|
|
5
|
+
value: T;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type ValueOrObject<T> = ObjectWithIdAndValue<T> | T;
|
|
9
|
+
|
|
10
|
+
export type ValueOrObjectArray<T> = ObjectWithIdAndValue<T>[] | T[];
|
|
11
|
+
|
|
12
|
+
export function isObjectWithIdAndValue<T>(
|
|
13
|
+
valueOrObject: ValueOrObject<T>,
|
|
14
|
+
): valueOrObject is ObjectWithIdAndValue<T> {
|
|
15
|
+
return Boolean(_.isObject(valueOrObject) && !_.isArray(valueOrObject) && valueOrObject.value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Helper class representing a scalar with an associated id.
|
|
20
|
+
*/
|
|
21
|
+
export class ScalarWithId<T> {
|
|
22
|
+
id: number;
|
|
23
|
+
|
|
24
|
+
value: T;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create a an array with ids.
|
|
28
|
+
* @param valueOrObject - a ScalarWithID, or any other type.
|
|
29
|
+
* @param id - numerical id (Integer).
|
|
30
|
+
*/
|
|
31
|
+
constructor(valueOrObject: ValueOrObject<T>, id = 0) {
|
|
32
|
+
// if already passing a ScalarWithId => preserve original
|
|
33
|
+
if (isObjectWithIdAndValue(valueOrObject)) {
|
|
34
|
+
// NOTE - Arrays are Objects too
|
|
35
|
+
this.id = valueOrObject.id;
|
|
36
|
+
this.value = valueOrObject.value;
|
|
37
|
+
} else {
|
|
38
|
+
this.id = id;
|
|
39
|
+
this.value = valueOrObject;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Serialize class instance to JSON.
|
|
45
|
+
* @example {"id" : 0, "value" : "Si" }
|
|
46
|
+
*/
|
|
47
|
+
toJSON(): ObjectWithIdAndValue<T> {
|
|
48
|
+
return {
|
|
49
|
+
id: this.id,
|
|
50
|
+
value: this.value,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|