@mat3ra/made 2026.8.7-0 → 2026.8.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/.mocharc.json +2 -2
- package/dist/js/Material.d.ts +219 -0
- package/dist/js/Material.js +457 -0
- package/dist/js/basis/basis.d.ts +14 -9
- package/dist/js/basis/basis.js +15 -13
- package/dist/js/basis/constrained_basis.d.ts +9 -7
- package/dist/js/basis/constrained_basis.js +4 -4
- package/dist/js/generated/MaterialSchemaMixin.d.ts +5 -0
- package/dist/js/generated/MaterialSchemaMixin.js +69 -0
- package/dist/js/lattice/lattice.d.ts +4 -3
- package/dist/js/lattice/lattice.js +1 -2
- package/dist/js/made.d.ts +12 -12
- package/dist/js/made.js +38 -5
- package/dist/js/parsers/espresso.d.ts +2 -3
- package/dist/js/parsers/espresso.js +0 -1
- package/dist/js/parsers/native_format_parsers.d.ts +9 -8
- package/dist/js/parsers/native_format_parsers.js +6 -6
- package/dist/js/parsers/parsers.d.ts +6 -6
- package/dist/js/parsers/poscar.d.ts +5 -4
- package/dist/js/parsers/poscar.js +3 -2
- package/dist/js/parsers/xyz.d.ts +3 -5
- package/dist/js/parsers/xyz.js +3 -4
- package/dist/js/parsers/xyz_combinatorial_basis.js +3 -1
- package/dist/js/tools/basis.d.ts +1 -1
- package/dist/js/tools/index.d.ts +7 -7
- package/dist/js/tools/material.d.ts +1 -1
- package/dist/js/tools/material.js +8 -7
- package/dist/js/tools/supercell.d.ts +4 -5
- package/dist/js/tools/supercell.js +2 -4
- package/dist/js/tools/surface.d.ts +4 -4
- package/dist/js/tools/surface.js +2 -7
- package/package.json +6 -6
- package/scripts/generate-mixins.ts +28 -0
- package/src/js/Material.ts +618 -0
- package/src/js/basis/basis.ts +38 -25
- package/src/js/basis/constrained_basis.ts +12 -11
- package/src/js/basis/coordinates.ts +0 -1
- package/src/js/cell/cell.ts +0 -1
- package/src/js/generated/MaterialSchemaMixin.ts +79 -0
- package/src/js/lattice/lattice.ts +6 -4
- package/src/js/lattice/reciprocal/lattice_reciprocal.ts +19 -6
- package/src/js/made.ts +1 -1
- package/src/js/parsers/espresso.ts +2 -3
- package/src/js/parsers/native_format_parsers.ts +9 -8
- package/src/js/parsers/poscar.ts +12 -6
- package/src/js/parsers/xyz.ts +9 -6
- package/src/js/parsers/xyz_combinatorial_basis.ts +5 -2
- package/src/js/tools/basis.ts +0 -1
- package/src/js/tools/cell.ts +0 -1
- package/src/js/tools/material.ts +13 -11
- package/src/js/tools/supercell.ts +8 -7
- package/src/js/tools/surface.ts +7 -17
- package/src/py/mat3ra/made/material.py +6 -5
- package/tests/fixtures/si-standata.json +2 -2
- package/tests/js/basis/basis.ts +8 -8
- package/tests/js/fixtures.ts +12 -9
- package/tests/js/material/material.ts +161 -0
- package/tests/js/parsers/espresso.ts +2 -5
- package/tests/js/parsers/poscar.ts +2 -2
- package/tests/js/register-esse-schemas.cjs +10 -0
- package/tests/js/tools/supercell.ts +2 -2
- package/tests/js/tools/surface.ts +6 -10
- package/dist/js/material.d.ts +0 -169
- package/dist/js/material.js +0 -362
- package/src/js/material.ts +0 -458
- package/tests/js/material.test.ts +0 -42
package/src/js/basis/basis.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
2
|
import { getElectronegativity, getElementAtomicRadius } from "@exabyte-io/periodic-table.js";
|
|
3
3
|
import { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
BaseInMemoryEntitySchema,
|
|
6
|
+
BasisSchema,
|
|
7
|
+
Coordinate3DSchema,
|
|
8
|
+
Vector3DSchema,
|
|
9
|
+
} from "@mat3ra/esse/dist/js/types";
|
|
5
10
|
import { Utils } from "@mat3ra/utils";
|
|
6
11
|
import { chain, toPairs, uniq, values } from "lodash";
|
|
7
12
|
|
|
8
13
|
import { Cell } from "../cell/cell";
|
|
9
14
|
import { ATOMIC_COORD_UNITS, HASH_TOLERANCE } from "../constants";
|
|
10
|
-
|
|
11
15
|
import {
|
|
12
16
|
defaultNonPeriodicMinimumLatticeSize,
|
|
13
17
|
diatomicLatticePaddingFactor,
|
|
@@ -72,7 +76,11 @@ const DEFAULT_BASIS_CONFIG = {
|
|
|
72
76
|
units: "crystal",
|
|
73
77
|
};
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
type BasisEntitySchema<S extends BasisConfig = BasisConfig> = S & BaseInMemoryEntitySchema;
|
|
80
|
+
|
|
81
|
+
// Keep `{` on same line as `implements` to satisfy brace-style (conflicts with Prettier multi-line heritage).
|
|
82
|
+
// prettier-ignore
|
|
83
|
+
export class Basis<S extends BasisConfig = BasisConfig> extends InMemoryEntity<BasisEntitySchema<S>> implements BasisSchema {
|
|
76
84
|
static defaultConfig: BasisSchema = DEFAULT_BASIS_CONFIG as BasisSchema;
|
|
77
85
|
|
|
78
86
|
units: BasisSchema["units"];
|
|
@@ -122,8 +130,9 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
122
130
|
);
|
|
123
131
|
}
|
|
124
132
|
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
// NoInfer: keep default S (or an explicit type arg) instead of inferring S from the config literal.
|
|
134
|
+
constructor(config: NoInfer<S> = Basis.defaultConfig as NoInfer<S>) {
|
|
135
|
+
super(config as BasisEntitySchema<S>);
|
|
127
136
|
const { elements, coordinates, units, labels } = config;
|
|
128
137
|
this.cell = new Cell(config.cell);
|
|
129
138
|
this.units = units || (ATOMIC_COORD_UNITS.crystal as BasisSchema["units"]);
|
|
@@ -156,20 +165,19 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
156
165
|
this._labels = Labels.fromObjects(labels || []);
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
168
|
+
toJSON(
|
|
169
|
+
exclude: (keyof BasisEntitySchema<S>)[] = ["cell"] as (keyof BasisEntitySchema<S>)[],
|
|
170
|
+
): BasisEntitySchema<S> {
|
|
162
171
|
return {
|
|
163
172
|
...super.toJSON(exclude),
|
|
164
173
|
elements: this.elements,
|
|
165
174
|
coordinates: this.coordinates,
|
|
166
175
|
units: this.units,
|
|
167
176
|
...(this.labels?.length ? { labels: this.labels } : {}),
|
|
168
|
-
}
|
|
177
|
+
} as BasisEntitySchema<S>;
|
|
169
178
|
}
|
|
170
179
|
|
|
171
|
-
|
|
172
|
-
override clone(): Basis {
|
|
180
|
+
override clone(): this {
|
|
173
181
|
const instance = super.clone();
|
|
174
182
|
instance.cell = this.cell.clone();
|
|
175
183
|
return instance;
|
|
@@ -205,16 +213,18 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
205
213
|
return this.units === ATOMIC_COORD_UNITS.crystal;
|
|
206
214
|
}
|
|
207
215
|
|
|
208
|
-
toCartesian()
|
|
209
|
-
if (this.isInCartesianUnits) return;
|
|
216
|
+
toCartesian() {
|
|
217
|
+
if (this.isInCartesianUnits) return this;
|
|
210
218
|
this._coordinates.mapArrayInPlace((point) => this.cell.convertPointToCartesian(point));
|
|
211
219
|
this.units = ATOMIC_COORD_UNITS.cartesian as BasisSchema["units"];
|
|
220
|
+
return this;
|
|
212
221
|
}
|
|
213
222
|
|
|
214
|
-
toCrystal()
|
|
215
|
-
if (this.isInCrystalUnits) return;
|
|
223
|
+
toCrystal() {
|
|
224
|
+
if (this.isInCrystalUnits) return this;
|
|
216
225
|
this._coordinates.mapArrayInPlace((point) => this.cell.convertPointToCrystal(point));
|
|
217
226
|
this.units = ATOMIC_COORD_UNITS.crystal as BasisSchema["units"];
|
|
227
|
+
return this;
|
|
218
228
|
}
|
|
219
229
|
|
|
220
230
|
getElementByIndex(idx: number): AtomicElementValue {
|
|
@@ -393,7 +403,9 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
393
403
|
const element = entry[0];
|
|
394
404
|
const coordinate = entry[1];
|
|
395
405
|
const atomicLabel = entry[2];
|
|
396
|
-
const toleratedCoordinate = coordinate.map((x) =>
|
|
406
|
+
const toleratedCoordinate = coordinate.map((x) =>
|
|
407
|
+
Utils.math.roundCustom(x, HASH_TOLERANCE),
|
|
408
|
+
);
|
|
397
409
|
return `${element}${atomicLabel} ${toleratedCoordinate.join()}`;
|
|
398
410
|
});
|
|
399
411
|
return `${standardRep.sort().join(";")};`;
|
|
@@ -416,7 +428,7 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
416
428
|
|
|
417
429
|
/* Returns array of atomic labels E.g., ["1", "2", "", ""] */
|
|
418
430
|
get atomicLabelsArray(): string[] {
|
|
419
|
-
const labelsArray = Array.from({ length: this.elements.length }, (
|
|
431
|
+
const labelsArray = Array.from({ length: this.elements.length }, () => "");
|
|
420
432
|
// https://dev.to/maafaishal/benchmarking-for-while-forof-and-arrayforeach-using-performancenow-1jjg
|
|
421
433
|
if (this.labels?.length) {
|
|
422
434
|
for (let i = 0; i < this.labels.length; i++) {
|
|
@@ -461,7 +473,7 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
461
473
|
* @summary Returns true if bases are equal, otherwise - false.
|
|
462
474
|
* @param anotherBasisClsInstance {Basis} Another Basis.
|
|
463
475
|
*/
|
|
464
|
-
isEqualTo(anotherBasisClsInstance:
|
|
476
|
+
isEqualTo(anotherBasisClsInstance: { hashString: string }): boolean {
|
|
465
477
|
return this.hashString === anotherBasisClsInstance.hashString;
|
|
466
478
|
}
|
|
467
479
|
|
|
@@ -469,7 +481,7 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
469
481
|
* @summary Returns true if basis cells are equal, otherwise - false.
|
|
470
482
|
* @param anotherBasisClsInstance {Basis} Another Basis.
|
|
471
483
|
*/
|
|
472
|
-
hasEquivalentCellTo(anotherBasisClsInstance:
|
|
484
|
+
hasEquivalentCellTo(anotherBasisClsInstance: { cell: Cell }): boolean {
|
|
473
485
|
return !this.cell.vectorArrays
|
|
474
486
|
.map((vector, idx) => {
|
|
475
487
|
return Utils.math.vEqualWithTolerance(
|
|
@@ -576,12 +588,13 @@ export class Basis extends InMemoryEntity implements BasisSchema {
|
|
|
576
588
|
this._coordinates.getElementValueByIndex(i) as Coordinate3DSchema,
|
|
577
589
|
this._coordinates.getElementValueByIndex(j) as Coordinate3DSchema,
|
|
578
590
|
);
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
591
|
+
if (distance) {
|
|
592
|
+
if (extremum === "max" && distance > resultDistance) {
|
|
593
|
+
resultDistance = distance;
|
|
594
|
+
}
|
|
595
|
+
if (extremum === "min" && distance < resultDistance) {
|
|
596
|
+
resultDistance = distance;
|
|
597
|
+
}
|
|
585
598
|
}
|
|
586
599
|
}
|
|
587
600
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { AtomicConstraintsSchema } from "@mat3ra/esse/dist/js/types";
|
|
1
|
+
import { AtomicConstraintsSchema, BasisConstrainedSchema } from "@mat3ra/esse/dist/js/types";
|
|
2
2
|
|
|
3
|
+
import { Cell } from "../cell/cell";
|
|
3
4
|
import { AtomicConstraints, AtomicConstraintValue, Constraint } from "../constraints/constraints";
|
|
4
|
-
import { Basis,
|
|
5
|
+
import { Basis, ElementsAndCoordinatesConfig } from "./basis";
|
|
5
6
|
import { AtomicCoordinateValue, Coordinate } from "./coordinates";
|
|
6
7
|
import { AtomicElementValue } from "./elements";
|
|
7
8
|
import { ElementWithLabel } from "./helpers";
|
|
8
9
|
import { AtomicLabelValue } from "./labels";
|
|
9
10
|
|
|
10
|
-
export interface ConstrainedBasisConfig extends
|
|
11
|
-
|
|
11
|
+
export interface ConstrainedBasisConfig extends BasisConstrainedSchema {
|
|
12
|
+
cell?: Cell;
|
|
13
|
+
isEmpty?: boolean;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface ElementsCoordinatesAndConstraintsConfig extends ElementsAndCoordinatesConfig {
|
|
@@ -19,13 +21,12 @@ export interface ElementsCoordinatesAndConstraintsConfig extends ElementsAndCoor
|
|
|
19
21
|
* @summary Extension of the Basis class able to deal with atomic constraints.
|
|
20
22
|
* @extends Basis
|
|
21
23
|
*/
|
|
22
|
-
export class ConstrainedBasis extends Basis {
|
|
23
|
-
_constraints: AtomicConstraints;
|
|
24
|
+
export class ConstrainedBasis extends Basis<ConstrainedBasisConfig> {
|
|
25
|
+
private _constraints: AtomicConstraints;
|
|
24
26
|
|
|
25
27
|
constructor(config: ConstrainedBasisConfig) {
|
|
26
28
|
super(config);
|
|
27
|
-
|
|
28
|
-
this._constraints = AtomicConstraints.fromObjects(constraints || []); // `constraints` is an Array with ids
|
|
29
|
+
this._constraints = AtomicConstraints.fromObjects(config.constraints ?? []); // `constraints` is an Array with ids
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
static fromElementsCoordinatesAndConstraints(
|
|
@@ -51,9 +52,9 @@ export class ConstrainedBasis extends Basis {
|
|
|
51
52
|
return AtomicConstraints.fromObjects(this.constraints);
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
override toJSON(): ConstrainedBasisConfig {
|
|
55
|
+
override toJSON(exclude: (keyof ConstrainedBasisConfig)[] = ["cell"]): ConstrainedBasisConfig {
|
|
55
56
|
return {
|
|
56
|
-
...super.toJSON(),
|
|
57
|
+
...super.toJSON(exclude as (keyof ConstrainedBasisConfig)[]),
|
|
57
58
|
constraints: this.constraints,
|
|
58
59
|
};
|
|
59
60
|
}
|
|
@@ -75,7 +76,7 @@ export class ConstrainedBasis extends Basis {
|
|
|
75
76
|
AtomicCoordinateValue,
|
|
76
77
|
AtomicConstraintValue,
|
|
77
78
|
][] {
|
|
78
|
-
return this._elements.values.map((element:
|
|
79
|
+
return this._elements.values.map((element: AtomicElementValue, idx: number) => {
|
|
79
80
|
const coordinate = this.getCoordinateValueByIndex(idx);
|
|
80
81
|
const constraint = this.getConstraintByIndex(idx);
|
|
81
82
|
const label = this.atomicLabelsArray[idx];
|
package/src/js/cell/cell.ts
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
|
|
2
|
+
import type {
|
|
3
|
+
BaseInMemoryEntitySchema,
|
|
4
|
+
MaterialPropertiesSchema,
|
|
5
|
+
} from "@mat3ra/esse/dist/js/types";
|
|
6
|
+
|
|
7
|
+
export type MaterialSchemaMixin = MaterialPropertiesSchema;
|
|
8
|
+
|
|
9
|
+
export type MaterialInMemoryEntity = InMemoryEntity<BaseInMemoryEntitySchema & MaterialSchemaMixin>;
|
|
10
|
+
|
|
11
|
+
export function materialSchemaMixin<T extends InMemoryEntity>(
|
|
12
|
+
item: InMemoryEntity,
|
|
13
|
+
): asserts item is T & MaterialSchemaMixin {
|
|
14
|
+
// @ts-expect-error
|
|
15
|
+
const properties: InMemoryEntity<MaterialSchemaMixin> & MaterialSchemaMixin = {
|
|
16
|
+
get formula() {
|
|
17
|
+
return this.prop("formula");
|
|
18
|
+
},
|
|
19
|
+
set formula(value: MaterialPropertiesSchema["formula"]) {
|
|
20
|
+
this.setProp("formula", value);
|
|
21
|
+
},
|
|
22
|
+
get unitCellFormula() {
|
|
23
|
+
return this.prop("unitCellFormula");
|
|
24
|
+
},
|
|
25
|
+
set unitCellFormula(value: MaterialPropertiesSchema["unitCellFormula"]) {
|
|
26
|
+
this.setProp("unitCellFormula", value);
|
|
27
|
+
},
|
|
28
|
+
get basis() {
|
|
29
|
+
return this.requiredProp("basis");
|
|
30
|
+
},
|
|
31
|
+
set basis(value: MaterialPropertiesSchema["basis"]) {
|
|
32
|
+
this.setProp("basis", value);
|
|
33
|
+
},
|
|
34
|
+
get lattice() {
|
|
35
|
+
return this.requiredProp("lattice");
|
|
36
|
+
},
|
|
37
|
+
set lattice(value: MaterialPropertiesSchema["lattice"]) {
|
|
38
|
+
this.setProp("lattice", value);
|
|
39
|
+
},
|
|
40
|
+
get derivedProperties() {
|
|
41
|
+
return this.prop("derivedProperties");
|
|
42
|
+
},
|
|
43
|
+
set derivedProperties(value: MaterialPropertiesSchema["derivedProperties"]) {
|
|
44
|
+
this.setProp("derivedProperties", value);
|
|
45
|
+
},
|
|
46
|
+
get external() {
|
|
47
|
+
return this.prop("external");
|
|
48
|
+
},
|
|
49
|
+
set external(value: MaterialPropertiesSchema["external"]) {
|
|
50
|
+
this.setProp("external", value);
|
|
51
|
+
},
|
|
52
|
+
get src() {
|
|
53
|
+
return this.prop("src");
|
|
54
|
+
},
|
|
55
|
+
set src(value: MaterialPropertiesSchema["src"]) {
|
|
56
|
+
this.setProp("src", value);
|
|
57
|
+
},
|
|
58
|
+
get icsdId() {
|
|
59
|
+
return this.prop("icsdId");
|
|
60
|
+
},
|
|
61
|
+
set icsdId(value: MaterialPropertiesSchema["icsdId"]) {
|
|
62
|
+
this.setProp("icsdId", value);
|
|
63
|
+
},
|
|
64
|
+
get isNonPeriodic() {
|
|
65
|
+
return this.prop("isNonPeriodic");
|
|
66
|
+
},
|
|
67
|
+
set isNonPeriodic(value: MaterialPropertiesSchema["isNonPeriodic"]) {
|
|
68
|
+
this.setProp("isNonPeriodic", value);
|
|
69
|
+
},
|
|
70
|
+
get consistencyChecks() {
|
|
71
|
+
return this.prop("consistencyChecks");
|
|
72
|
+
},
|
|
73
|
+
set consistencyChecks(value: MaterialPropertiesSchema["consistencyChecks"]) {
|
|
74
|
+
this.setProp("consistencyChecks", value);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
|
|
79
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
|
|
2
2
|
import {
|
|
3
|
+
BaseInMemoryEntitySchema,
|
|
3
4
|
Coordinate3DSchema,
|
|
4
5
|
LatticeSchema,
|
|
5
6
|
LatticeTypeEnum,
|
|
@@ -30,7 +31,9 @@ export class LatticeVectors extends Cell implements LatticeVectorsSchema {}
|
|
|
30
31
|
|
|
31
32
|
export type { LatticeVectorsSchema };
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
type LatticeEntitySchema = LatticeSchema & BaseInMemoryEntitySchema;
|
|
35
|
+
|
|
36
|
+
export class Lattice extends InMemoryEntity<LatticeEntitySchema> implements LatticeSchema {
|
|
34
37
|
static defaultConfig: LatticeSchema = {
|
|
35
38
|
a: 1,
|
|
36
39
|
b: 1,
|
|
@@ -296,11 +299,10 @@ export class Lattice extends InMemoryEntity implements LatticeSchema {
|
|
|
296
299
|
return object;
|
|
297
300
|
}
|
|
298
301
|
|
|
299
|
-
|
|
300
|
-
toJSON(exclude?: string[]): LatticeSchema {
|
|
302
|
+
toJSON(exclude: (keyof LatticeSchema)[] = []): LatticeSchema {
|
|
301
303
|
return {
|
|
302
304
|
...super.toJSON(exclude),
|
|
303
305
|
vectors: this.vectors.toJSON(),
|
|
304
|
-
}
|
|
306
|
+
};
|
|
305
307
|
}
|
|
306
308
|
}
|
|
@@ -7,7 +7,6 @@ import { Lattice } from "../lattice";
|
|
|
7
7
|
import { paths } from "./paths";
|
|
8
8
|
import { symmetryPoints } from "./symmetry_points";
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
export type KPointCoordinates = number[];
|
|
12
11
|
export type KPointPath = Array<{
|
|
13
12
|
point: string;
|
|
@@ -47,9 +46,18 @@ export class ReciprocalLattice extends Lattice {
|
|
|
47
46
|
Utils.math.cross(vectors_[1], vectors_[2]),
|
|
48
47
|
) as unknown as number) / a;
|
|
49
48
|
return [
|
|
50
|
-
Utils.math.multiply(
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
Utils.math.multiply(
|
|
50
|
+
Utils.math.cross(vectors_[1], vectors_[2]),
|
|
51
|
+
1 / divider,
|
|
52
|
+
) as Vector3DSchema,
|
|
53
|
+
Utils.math.multiply(
|
|
54
|
+
Utils.math.cross(vectors_[2], vectors_[0]),
|
|
55
|
+
1 / divider,
|
|
56
|
+
) as Vector3DSchema,
|
|
57
|
+
Utils.math.multiply(
|
|
58
|
+
Utils.math.cross(vectors_[0], vectors_[1]),
|
|
59
|
+
1 / divider,
|
|
60
|
+
) as Vector3DSchema,
|
|
53
61
|
];
|
|
54
62
|
}
|
|
55
63
|
|
|
@@ -57,7 +65,9 @@ export class ReciprocalLattice extends Lattice {
|
|
|
57
65
|
* Norms of reciprocal vectors.
|
|
58
66
|
*/
|
|
59
67
|
get reciprocalVectorNorms(): Vector3DSchema {
|
|
60
|
-
return this.reciprocalVectors.map(
|
|
68
|
+
return this.reciprocalVectors.map(
|
|
69
|
+
(vec) => Utils.math.norm(vec) as number,
|
|
70
|
+
) as Vector3DSchema;
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
/**
|
|
@@ -167,7 +177,10 @@ export class ReciprocalLattice extends Lattice {
|
|
|
167
177
|
getDimensionsFromSpacing(spacing: number, units: string = ATOMIC_COORD_UNITS.cartesian) {
|
|
168
178
|
const factor: number = this.conversionTable[units][ATOMIC_COORD_UNITS.cartesian] || 1;
|
|
169
179
|
return this.reciprocalVectorNorms.map((norm: number) => {
|
|
170
|
-
return Utils.math.max(
|
|
180
|
+
return Utils.math.max(
|
|
181
|
+
1,
|
|
182
|
+
Utils.math.ceil(lodash.round(norm / (spacing * factor), 4)),
|
|
183
|
+
) as number;
|
|
171
184
|
}) as Vector3DSchema;
|
|
172
185
|
}
|
|
173
186
|
|
package/src/js/made.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { DEFAULT_LATTICE_UNITS, LATTICE_TYPE_CONFIGS } from "./lattice/lattice_types";
|
|
12
12
|
import { ReciprocalLattice } from "./lattice/reciprocal/lattice_reciprocal";
|
|
13
13
|
import { UnitCell } from "./lattice/unit_cell";
|
|
14
|
-
import { defaultMaterialConfig
|
|
14
|
+
import Material, { defaultMaterialConfig } from "./Material";
|
|
15
15
|
import parsers from "./parsers/parsers";
|
|
16
16
|
import tools from "./tools/index";
|
|
17
17
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MaterialSchema } from "@mat3ra/esse/dist/js/types";
|
|
1
|
+
import { MaterialEnhancedSchema, MaterialSchema } from "@mat3ra/esse/dist/js/types";
|
|
2
2
|
import { map } from "lodash";
|
|
3
3
|
import s from "underscore.string";
|
|
4
4
|
|
|
@@ -7,9 +7,8 @@ import xyz from "./xyz";
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Construct textual representation of a materialOrConfig according to Quantum ESPRESSO pw.x input format.
|
|
10
|
-
* @param materialOrConfig - material class instance or its config object
|
|
11
10
|
*/
|
|
12
|
-
function toEspressoFormat(materialOrConfig: MaterialSchema): string {
|
|
11
|
+
function toEspressoFormat(materialOrConfig: MaterialSchema | MaterialEnhancedSchema): string {
|
|
13
12
|
const l = new Lattice(materialOrConfig.lattice);
|
|
14
13
|
const vectors = l.vectorArrays;
|
|
15
14
|
const vectorsAsString = map(vectors, (v) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MaterialConfig } from "../Material";
|
|
1
2
|
import Poscar from "./poscar";
|
|
2
3
|
|
|
3
4
|
const NATIVE_FORMAT = {
|
|
@@ -7,13 +8,13 @@ const NATIVE_FORMAT = {
|
|
|
7
8
|
PWX: "pwx",
|
|
8
9
|
XYZ: "xyz",
|
|
9
10
|
UNKNOWN: "unknown",
|
|
10
|
-
};
|
|
11
|
+
} as const;
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* @summary Detects the format of the input string
|
|
14
|
-
* @throws
|
|
15
|
-
* @param
|
|
16
|
-
* @returns
|
|
15
|
+
* @throws If the input string is unknown format
|
|
16
|
+
* @param text input string to detect format
|
|
17
|
+
* @returns Format of the input string
|
|
17
18
|
*/
|
|
18
19
|
function detectFormat(text: string) {
|
|
19
20
|
const jsonRegex = /^\s*\{/;
|
|
@@ -25,11 +26,11 @@ function detectFormat(text: string) {
|
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* @summary Function to handle conversion from native formats
|
|
28
|
-
* @param
|
|
29
|
-
* @throws
|
|
30
|
-
* @return
|
|
29
|
+
* @param text - input string to detect format and convert
|
|
30
|
+
* @throws If the input string is of unknown format
|
|
31
|
+
* @return Material config
|
|
31
32
|
*/
|
|
32
|
-
function convertFromNativeFormat(text: string) {
|
|
33
|
+
function convertFromNativeFormat(text: string): MaterialConfig {
|
|
33
34
|
const format = detectFormat(text);
|
|
34
35
|
|
|
35
36
|
switch (format) {
|
package/src/js/parsers/poscar.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BasisSchema,
|
|
3
3
|
Coordinate3DSchema,
|
|
4
|
+
MaterialEnhancedSchema,
|
|
4
5
|
MaterialSchema,
|
|
5
6
|
Vector3DSchema,
|
|
6
7
|
} from "@mat3ra/esse/dist/js/types";
|
|
@@ -14,7 +15,7 @@ import { Cell } from "../cell/cell";
|
|
|
14
15
|
import { ATOMIC_COORD_UNITS } from "../constants";
|
|
15
16
|
import { AtomicConstraintValue } from "../constraints/constraints";
|
|
16
17
|
import { Lattice } from "../lattice/lattice";
|
|
17
|
-
|
|
18
|
+
import type { MaterialConfig } from "../Material";
|
|
18
19
|
|
|
19
20
|
const _print = (x: number, printFormat = "%14.9f") => s.sprintf(printFormat, Utils.math.precise(x));
|
|
20
21
|
const _latticeVectorsToString = (vectors: Vector3DSchema[]) =>
|
|
@@ -24,15 +25,20 @@ const atomicConstraintsCharFromBool = (bool: boolean): string => (bool ? "T" : "
|
|
|
24
25
|
/**
|
|
25
26
|
* Obtain a textual representation of a material in POSCAR format.
|
|
26
27
|
* @param materialOrConfig - material class instance or config object.
|
|
27
|
-
* @param omitConstraints - whether to discard constraints
|
|
28
|
+
* @param omitConstraints - whether to discard constraints when serializing.
|
|
28
29
|
*/
|
|
29
|
-
function toPoscar(
|
|
30
|
+
function toPoscar(
|
|
31
|
+
materialOrConfig: MaterialSchema | MaterialEnhancedSchema,
|
|
32
|
+
omitConstraints = false,
|
|
33
|
+
): string {
|
|
30
34
|
const lattice = new Lattice(materialOrConfig.lattice);
|
|
31
35
|
const vectorsAsString = _latticeVectorsToString(lattice.vectorArrays);
|
|
32
|
-
|
|
36
|
+
const constraints =
|
|
37
|
+
"constraints" in materialOrConfig.basis ? materialOrConfig.basis.constraints : [];
|
|
33
38
|
const basis = new ConstrainedBasis({
|
|
34
39
|
...materialOrConfig.basis,
|
|
35
40
|
cell: Cell.fromVectorsArray(lattice.vectorArrays),
|
|
41
|
+
constraints: omitConstraints ? [] : constraints,
|
|
36
42
|
});
|
|
37
43
|
const BasisLines: string[] = [];
|
|
38
44
|
let addSelectiveDynamics = false;
|
|
@@ -78,7 +84,7 @@ export function atomsCount(poscarFileContent: string): number {
|
|
|
78
84
|
* @param fileContent - POSCAR file content.
|
|
79
85
|
* @return Material config.
|
|
80
86
|
*/
|
|
81
|
-
function fromPoscar(fileContent: string):
|
|
87
|
+
function fromPoscar(fileContent: string): MaterialConfig {
|
|
82
88
|
const cleanContent = Utils.str.removeCommentsFromSourceCode(fileContent, "fortran");
|
|
83
89
|
const lines = cleanContent.split("\n");
|
|
84
90
|
|
|
@@ -151,7 +157,7 @@ function fromPoscar(fileContent: string): object {
|
|
|
151
157
|
constraints,
|
|
152
158
|
});
|
|
153
159
|
|
|
154
|
-
const materialConfig = {
|
|
160
|
+
const materialConfig: MaterialConfig = {
|
|
155
161
|
lattice: lattice.toJSON(),
|
|
156
162
|
basis: basis.toJSON(),
|
|
157
163
|
name: comment,
|
package/src/js/parsers/xyz.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MaterialSchema } from "@mat3ra/esse/dist/js/types";
|
|
1
|
+
import { MaterialEnhancedSchema, MaterialSchema } from "@mat3ra/esse/dist/js/types";
|
|
2
2
|
import { isEmpty, isNaN, map } from "lodash";
|
|
3
3
|
import s from "underscore.string";
|
|
4
4
|
|
|
@@ -161,16 +161,19 @@ function fromBasis(basisClsInstance: ConstrainedBasis, coordinatePrintFormat: st
|
|
|
161
161
|
|
|
162
162
|
/**
|
|
163
163
|
* Create XYZ from Material class instance (or its JSON config).
|
|
164
|
-
*
|
|
165
|
-
* @param fractional Coordinate units as fractional.
|
|
166
|
-
* @return Class Instance
|
|
164
|
+
* Prefer fromBasis when you already have a ConstrainedBasis instance.
|
|
167
165
|
*/
|
|
168
|
-
function fromMaterial(
|
|
166
|
+
function fromMaterial(
|
|
167
|
+
materialOrConfig: MaterialSchema | MaterialEnhancedSchema,
|
|
168
|
+
fractional = false,
|
|
169
|
+
): string {
|
|
169
170
|
const lattice = new Lattice(materialOrConfig.lattice);
|
|
170
|
-
|
|
171
|
+
const constraints =
|
|
172
|
+
"constraints" in materialOrConfig.basis ? materialOrConfig.basis.constraints : [];
|
|
171
173
|
const basis = new ConstrainedBasis({
|
|
172
174
|
...materialOrConfig.basis,
|
|
173
175
|
cell: Cell.fromVectorsArray(lattice.vectorArrays),
|
|
176
|
+
constraints,
|
|
174
177
|
});
|
|
175
178
|
if (fractional) {
|
|
176
179
|
basis.toCrystal();
|
|
@@ -8,7 +8,6 @@ import { AtomicCoordinateValue } from "../basis/coordinates";
|
|
|
8
8
|
import { AtomicElementValue } from "../basis/elements";
|
|
9
9
|
import { Cell } from "../cell/cell";
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
/**
|
|
13
12
|
* @summary Combinatorial XYZ basis class and related. Create and get all information about basis and elements in it.
|
|
14
13
|
* Constructor accepts string in extended XYZ format. Extended XYZ format is as follows:
|
|
@@ -225,7 +224,11 @@ export class CombinatorialBasis {
|
|
|
225
224
|
dimensions.push(itemsSet);
|
|
226
225
|
});
|
|
227
226
|
// @ts-ignore // We're multiplying objects with math, not numbers. No type casting will help.
|
|
228
|
-
const basisSet = Utils.math.cartesianProduct.apply(
|
|
227
|
+
const basisSet = Utils.math.cartesianProduct.apply(
|
|
228
|
+
null,
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
dimensions,
|
|
231
|
+
) as ElementWithCoordinate[][];
|
|
229
232
|
return basisSet.map((basis: ElementWithCoordinate[]) =>
|
|
230
233
|
basis.filter((entry) => entry.element !== VACANCY_CHARACTER),
|
|
231
234
|
);
|
package/src/js/tools/basis.ts
CHANGED
package/src/js/tools/cell.ts
CHANGED
package/src/js/tools/material.ts
CHANGED
|
@@ -3,8 +3,7 @@ import { Utils } from "@mat3ra/utils";
|
|
|
3
3
|
|
|
4
4
|
import { ATOMIC_COORD_UNITS } from "../constants";
|
|
5
5
|
import { Lattice } from "../lattice/lattice";
|
|
6
|
-
import
|
|
7
|
-
|
|
6
|
+
import Material from "../Material";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Scales one lattice vector for the given material
|
|
@@ -18,9 +17,9 @@ function scaleOneLatticeVector(material: Material, key: "a" | "b" | "c" = "a", f
|
|
|
18
17
|
if (lattice.vectors === undefined) {
|
|
19
18
|
throw new Error("Lattice vectors are undefined");
|
|
20
19
|
}
|
|
21
|
-
lattice.vectors[key] = lattice.vectors
|
|
20
|
+
lattice.vectors[key] = lattice.vectors[key].map((v) => v * factor) as Vector3DSchema;
|
|
22
21
|
|
|
23
|
-
material.
|
|
22
|
+
material.setLattice(Lattice.fromVectors(lattice.vectors).toJSON());
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
/**
|
|
@@ -29,10 +28,12 @@ function scaleOneLatticeVector(material: Material, key: "a" | "b" | "c" = "a", f
|
|
|
29
28
|
* @param material {Material}
|
|
30
29
|
*/
|
|
31
30
|
function scaleLatticeToMakeNonPeriodic(material: Material) {
|
|
32
|
-
material.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
material.setLattice(
|
|
32
|
+
Lattice.fromConfigPartial({
|
|
33
|
+
a: material.getBasis().getMinimumLatticeSize(),
|
|
34
|
+
type: "CUB",
|
|
35
|
+
} as LatticeSchema).toJSON(),
|
|
36
|
+
);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
/**
|
|
@@ -41,13 +42,14 @@ function scaleLatticeToMakeNonPeriodic(material: Material) {
|
|
|
41
42
|
* @param material {Material}
|
|
42
43
|
* */
|
|
43
44
|
function translateAtomsToCenter(material: Material) {
|
|
44
|
-
const
|
|
45
|
+
const basis = material.getBasis();
|
|
46
|
+
const originalUnits = basis.units;
|
|
45
47
|
material.toCartesian();
|
|
46
|
-
const updatedBasis =
|
|
48
|
+
const updatedBasis = basis.toCartesian();
|
|
47
49
|
const centerOfCoordinates = updatedBasis.centerOfCoordinatesPoint;
|
|
48
50
|
const centerOfLattice = Utils.math.multiply(
|
|
49
51
|
0.5,
|
|
50
|
-
material.
|
|
52
|
+
material.getLattice().vectorArrays.reduce((a, b) => Utils.math.add(a, b) as Vector3DSchema),
|
|
51
53
|
);
|
|
52
54
|
const translationVector = Utils.math.subtract(centerOfLattice, centerOfCoordinates);
|
|
53
55
|
updatedBasis.translateByVector(translationVector as Vector3DSchema);
|