matsci-parse 0.1.2 → 0.3.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/main.js +725 -315
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
class
|
|
2
|
-
constructor(e, t
|
|
3
|
-
this.speciesIndex =
|
|
1
|
+
class v {
|
|
2
|
+
constructor(s, e, t = {}) {
|
|
3
|
+
this.speciesIndex = s, this.cart = e, this.props = t;
|
|
4
4
|
}
|
|
5
|
-
getProp(
|
|
6
|
-
return this.props[
|
|
5
|
+
getProp(s) {
|
|
6
|
+
return this.props[s];
|
|
7
7
|
}
|
|
8
|
-
setProp(
|
|
9
|
-
this.props[
|
|
8
|
+
setProp(s, e) {
|
|
9
|
+
this.props[s] = e;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
return
|
|
12
|
+
function B(m) {
|
|
13
|
+
return m.sites.some((s) => Array.isArray(s.props.selectiveDynamics));
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
return
|
|
15
|
+
function M(m) {
|
|
16
|
+
return m * Math.PI / 180;
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
return
|
|
20
|
-
(
|
|
18
|
+
function j(m, s) {
|
|
19
|
+
return m.map(
|
|
20
|
+
(e) => e[0] * s[0] + e[1] * s[1] + e[2] * s[2]
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
const a =
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
function k(m, s, e, t, i, o) {
|
|
24
|
+
const a = M(t), b = M(i), n = M(o), u = [m, 0, 0], h = [
|
|
25
|
+
s * Math.cos(n),
|
|
26
|
+
s * Math.sin(n),
|
|
27
27
|
0
|
|
28
|
-
],
|
|
29
|
-
return [
|
|
28
|
+
], c = e * Math.cos(b), l = e * (Math.cos(a) - Math.cos(b) * Math.cos(n)) / Math.sin(n), f = Math.sqrt(e * e - c * c - l * l);
|
|
29
|
+
return [u, h, [c, l, f]];
|
|
30
30
|
}
|
|
31
|
-
function
|
|
32
|
-
const [
|
|
31
|
+
function U(m, s) {
|
|
32
|
+
const [e, t, i] = s;
|
|
33
33
|
return [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
m[0] * e[0] + m[1] * t[0] + m[2] * i[0],
|
|
35
|
+
m[0] * e[1] + m[1] * t[1] + m[2] * i[1],
|
|
36
|
+
m[0] * e[2] + m[1] * t[2] + m[2] * i[2]
|
|
37
37
|
];
|
|
38
38
|
}
|
|
39
|
-
class
|
|
39
|
+
class I {
|
|
40
40
|
/**
|
|
41
41
|
* Creates a new CrystalStructure.
|
|
42
42
|
*
|
|
@@ -48,11 +48,11 @@ class w {
|
|
|
48
48
|
* @throws Will throw an error if lattice is not 3x3, species is not an array of strings, or sites are invalid
|
|
49
49
|
*/
|
|
50
50
|
constructor({
|
|
51
|
-
lattice:
|
|
52
|
-
species:
|
|
53
|
-
sites:
|
|
51
|
+
lattice: s,
|
|
52
|
+
species: e,
|
|
53
|
+
sites: t
|
|
54
54
|
}) {
|
|
55
|
-
this.lattice = this._validateLattice(
|
|
55
|
+
this.lattice = this._validateLattice(s), this.species = this._validateSpecies(e), this.sites = this._validateSites(t);
|
|
56
56
|
}
|
|
57
57
|
// ---------- Simple methods ----------
|
|
58
58
|
/** Number of sites in the structure */
|
|
@@ -63,22 +63,22 @@ class w {
|
|
|
63
63
|
* Returns the site at the specified index.
|
|
64
64
|
* @param i - Site index
|
|
65
65
|
*/
|
|
66
|
-
site(
|
|
67
|
-
return this.sites[
|
|
66
|
+
site(s) {
|
|
67
|
+
return this.sites[s];
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Returns the Cartesian coordinates of a site.
|
|
71
71
|
* @param i - Site index
|
|
72
72
|
*/
|
|
73
|
-
cartCoords(
|
|
74
|
-
return this.sites[
|
|
73
|
+
cartCoords(s) {
|
|
74
|
+
return this.sites[s].cart;
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Returns the chemical species of a site.
|
|
78
78
|
* @param i - Site index
|
|
79
79
|
*/
|
|
80
|
-
siteSpecies(
|
|
81
|
-
return this.species[this.sites[
|
|
80
|
+
siteSpecies(s) {
|
|
81
|
+
return this.species[this.sites[s].speciesIndex];
|
|
82
82
|
}
|
|
83
83
|
/** Returns the array of elements (species) in the structure */
|
|
84
84
|
get elements() {
|
|
@@ -92,11 +92,11 @@ class w {
|
|
|
92
92
|
* @param cart - Cartesian coordinates of the new site
|
|
93
93
|
* @param position - Optional index at which to insert the site. Defaults to appending at the end.
|
|
94
94
|
*/
|
|
95
|
-
addSite(e, t
|
|
96
|
-
let
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
95
|
+
addSite(s, e, t) {
|
|
96
|
+
let i = this.species.indexOf(s);
|
|
97
|
+
i === -1 && (this.species.push(s), i = this.species.length - 1);
|
|
98
|
+
const o = new v(i, e);
|
|
99
|
+
t === void 0 || t >= this.sites.length ? this.sites.push(o) : t < 0 ? this.sites.unshift(o) : this.sites.splice(t, 0, o);
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
102
|
* Removes a site from the crystal.
|
|
@@ -107,14 +107,14 @@ class w {
|
|
|
107
107
|
*
|
|
108
108
|
* @throws Will throw an error if index is out of bounds
|
|
109
109
|
*/
|
|
110
|
-
removeSite(
|
|
111
|
-
if (
|
|
110
|
+
removeSite(s) {
|
|
111
|
+
if (s < 0 || s >= this.sites.length)
|
|
112
112
|
throw new Error("siteIndex out of bounds");
|
|
113
|
-
const
|
|
113
|
+
const t = this.sites.splice(s, 1)[0].speciesIndex;
|
|
114
114
|
this.sites.some(
|
|
115
|
-
(
|
|
116
|
-
) || (this.species.splice(
|
|
117
|
-
|
|
115
|
+
(o) => o.speciesIndex === t
|
|
116
|
+
) || (this.species.splice(t, 1), this.sites.forEach((o) => {
|
|
117
|
+
o.speciesIndex > t && (o.speciesIndex -= 1);
|
|
118
118
|
}));
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
@@ -127,11 +127,11 @@ class w {
|
|
|
127
127
|
*
|
|
128
128
|
* @throws Will throw an error if siteIndex is out of bounds
|
|
129
129
|
*/
|
|
130
|
-
replaceSite(
|
|
131
|
-
if (
|
|
130
|
+
replaceSite(s, e) {
|
|
131
|
+
if (s < 0 || s >= this.sites.length)
|
|
132
132
|
throw new Error("siteIndex out of bounds");
|
|
133
|
-
const
|
|
134
|
-
this.removeSite(
|
|
133
|
+
const t = [...this.sites[s].cart];
|
|
134
|
+
this.removeSite(s), this.addSite(e, t, s);
|
|
135
135
|
}
|
|
136
136
|
/**
|
|
137
137
|
* Returns a new CrystalStructure transformed by a linear matrix.
|
|
@@ -146,39 +146,39 @@ class w {
|
|
|
146
146
|
*
|
|
147
147
|
* @throws Will throw an error if scale is not a number, a 3-element array, or a 3x3 matrix
|
|
148
148
|
*/
|
|
149
|
-
applyLatticeTransformation(
|
|
150
|
-
let
|
|
151
|
-
if (typeof
|
|
152
|
-
|
|
153
|
-
[
|
|
154
|
-
[0,
|
|
155
|
-
[0, 0,
|
|
149
|
+
applyLatticeTransformation(s) {
|
|
150
|
+
let e;
|
|
151
|
+
if (typeof s == "number")
|
|
152
|
+
e = [
|
|
153
|
+
[s, 0, 0],
|
|
154
|
+
[0, s, 0],
|
|
155
|
+
[0, 0, s]
|
|
156
156
|
];
|
|
157
|
-
else if (Array.isArray(
|
|
158
|
-
|
|
159
|
-
[
|
|
160
|
-
[0,
|
|
161
|
-
[0, 0,
|
|
157
|
+
else if (Array.isArray(s) && s.length === 3 && s.every((o) => typeof o == "number"))
|
|
158
|
+
e = [
|
|
159
|
+
[s[0], 0, 0],
|
|
160
|
+
[0, s[1], 0],
|
|
161
|
+
[0, 0, s[2]]
|
|
162
162
|
];
|
|
163
|
-
else if (Array.isArray(
|
|
164
|
-
|
|
163
|
+
else if (Array.isArray(s) && s.length === 3 && s.every((o) => Array.isArray(o) && o.length === 3))
|
|
164
|
+
e = s;
|
|
165
165
|
else
|
|
166
166
|
throw new Error(
|
|
167
167
|
"Scale must be a number, a 3-element array, or a 3x3 matrix"
|
|
168
168
|
);
|
|
169
|
-
const
|
|
170
|
-
(
|
|
171
|
-
),
|
|
172
|
-
const a =
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
const t = this.lattice.map(
|
|
170
|
+
(o) => j(e, o)
|
|
171
|
+
), i = this.sites.map((o) => {
|
|
172
|
+
const a = j(
|
|
173
|
+
e,
|
|
174
|
+
o.cart
|
|
175
175
|
);
|
|
176
|
-
return new
|
|
176
|
+
return new v(o.speciesIndex, a, o.props);
|
|
177
177
|
});
|
|
178
|
-
return new
|
|
179
|
-
lattice:
|
|
178
|
+
return new I({
|
|
179
|
+
lattice: t,
|
|
180
180
|
species: [...this.species],
|
|
181
|
-
sites:
|
|
181
|
+
sites: i
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
184
|
// ---------- Internal validation ----------
|
|
@@ -186,38 +186,38 @@ class w {
|
|
|
186
186
|
* Validates that the lattice is a 3x3 array of Cartesian vectors.
|
|
187
187
|
* @throws Will throw an error if lattice is invalid
|
|
188
188
|
*/
|
|
189
|
-
_validateLattice(
|
|
190
|
-
if (!Array.isArray(
|
|
189
|
+
_validateLattice(s) {
|
|
190
|
+
if (!Array.isArray(s) || s.length !== 3)
|
|
191
191
|
throw new Error("Lattice must be a 3x3 matrix");
|
|
192
|
-
return
|
|
193
|
-
if (!Array.isArray(
|
|
192
|
+
return s.forEach((e) => {
|
|
193
|
+
if (!Array.isArray(e) || e.length !== 3)
|
|
194
194
|
throw new Error("Lattice vectors must be length 3");
|
|
195
|
-
}),
|
|
195
|
+
}), s;
|
|
196
196
|
}
|
|
197
197
|
/**
|
|
198
198
|
* Validates that species is an array of strings.
|
|
199
199
|
* @throws Will throw an error if species array is invalid
|
|
200
200
|
*/
|
|
201
|
-
_validateSpecies(
|
|
202
|
-
if (!Array.isArray(
|
|
203
|
-
return
|
|
204
|
-
if (typeof
|
|
201
|
+
_validateSpecies(s) {
|
|
202
|
+
if (!Array.isArray(s)) throw new Error("Species must be an array");
|
|
203
|
+
return s.forEach((e) => {
|
|
204
|
+
if (typeof e != "string")
|
|
205
205
|
throw new Error("Species entries must be strings");
|
|
206
|
-
}),
|
|
206
|
+
}), s;
|
|
207
207
|
}
|
|
208
208
|
/**
|
|
209
209
|
* Validates the sites array, ensuring each site is a Site instance or a valid object.
|
|
210
210
|
* @throws Will throw an error if sites array is invalid
|
|
211
211
|
*/
|
|
212
|
-
_validateSites(
|
|
213
|
-
if (!Array.isArray(
|
|
214
|
-
return
|
|
215
|
-
if (
|
|
216
|
-
if (typeof
|
|
217
|
-
return this._validateSpeciesIndex(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
212
|
+
_validateSites(s) {
|
|
213
|
+
if (!Array.isArray(s)) throw new Error("Sites must be an array");
|
|
214
|
+
return s.map((e) => {
|
|
215
|
+
if (e instanceof v) return e;
|
|
216
|
+
if (typeof e == "object" && typeof e.speciesIndex == "number" && Array.isArray(e.cart) && e.cart.length === 3)
|
|
217
|
+
return this._validateSpeciesIndex(e.speciesIndex), new v(
|
|
218
|
+
e.speciesIndex,
|
|
219
|
+
e.cart,
|
|
220
|
+
e.props ?? {}
|
|
221
221
|
);
|
|
222
222
|
throw new Error(
|
|
223
223
|
"Each site must be a Site instance or a valid site object"
|
|
@@ -228,230 +228,305 @@ class w {
|
|
|
228
228
|
* Validates that a species index is within bounds.
|
|
229
229
|
* @throws Will throw an error if index is out of range
|
|
230
230
|
*/
|
|
231
|
-
_validateSpeciesIndex(
|
|
232
|
-
if (
|
|
231
|
+
_validateSpeciesIndex(s) {
|
|
232
|
+
if (s < 0 || s >= this.species.length)
|
|
233
233
|
throw new Error("speciesIndex out of bounds");
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
class X {
|
|
237
|
+
constructor(s) {
|
|
238
|
+
this.spatialUnits = "angstrom", this._invalid = !0;
|
|
239
|
+
const { origin: e, basis: t, shape: i, values: o, components: a = 1, units: b } = s, [n, u, h] = i;
|
|
240
|
+
if (o.length !== n * u * h * a)
|
|
241
|
+
throw new Error(
|
|
242
|
+
`Invalid values length: expected ${n * u * h * a}, got ${o.length}`
|
|
243
|
+
);
|
|
244
|
+
this.origin = e, this.basis = t, this.shape = i, this.values = o, this.components = a, this.units = b;
|
|
245
|
+
}
|
|
246
|
+
invalidate() {
|
|
247
|
+
this._invalid = !0;
|
|
248
|
+
}
|
|
249
|
+
map(s) {
|
|
250
|
+
const [e, t, i] = this.shape;
|
|
251
|
+
for (let o = 0; o < i; o++)
|
|
252
|
+
for (let a = 0; a < t; a++)
|
|
253
|
+
for (let b = 0; b < e; b++)
|
|
254
|
+
for (let n = 0; n < this.components; n++) {
|
|
255
|
+
const u = this.index(b, a, o, n);
|
|
256
|
+
this.values[u] = s(this.values[u], b, a, o, n);
|
|
257
|
+
}
|
|
258
|
+
this.invalidate();
|
|
259
|
+
}
|
|
260
|
+
min() {
|
|
261
|
+
return (this._invalid || this._min === void 0) && this.computeStats(), this._min;
|
|
262
|
+
}
|
|
263
|
+
max() {
|
|
264
|
+
return (this._invalid || this._max === void 0) && this.computeStats(), this._max;
|
|
265
|
+
}
|
|
266
|
+
mean() {
|
|
267
|
+
return (this._invalid || this._mean === void 0) && this.computeStats(), this._mean;
|
|
268
|
+
}
|
|
269
|
+
index(s, e, t, i = 0) {
|
|
270
|
+
const [o, a] = this.shape;
|
|
271
|
+
return (s + o * (e + a * t)) * this.components + i;
|
|
272
|
+
}
|
|
273
|
+
get(s, e, t, i = 0) {
|
|
274
|
+
return this.values[this.index(s, e, t, i)];
|
|
275
|
+
}
|
|
276
|
+
set(s, e, t, i, o) {
|
|
277
|
+
this.values[this.index(s, e, t, i)] = o, this.invalidate();
|
|
278
|
+
}
|
|
279
|
+
normalize() {
|
|
280
|
+
const s = this.min(), e = this.max();
|
|
281
|
+
this.map((t) => (t - s) / (e - s));
|
|
282
|
+
}
|
|
283
|
+
/** Convert grid index → Cartesian position */
|
|
284
|
+
position(s, e, t) {
|
|
285
|
+
const [i, o, a] = this.basis;
|
|
286
|
+
return [
|
|
287
|
+
this.origin[0] + s * i[0] + e * o[0] + t * a[0],
|
|
288
|
+
this.origin[1] + s * i[1] + e * o[1] + t * a[1],
|
|
289
|
+
this.origin[2] + s * i[2] + e * o[2] + t * a[2]
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
voxelVolume() {
|
|
293
|
+
const [s, e, t] = this.basis;
|
|
294
|
+
return Math.abs(
|
|
295
|
+
s[0] * (e[1] * t[2] - e[2] * t[1]) - s[1] * (e[0] * t[2] - e[2] * t[0]) + s[2] * (e[0] * t[1] - e[1] * t[0])
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
integral() {
|
|
299
|
+
return this.mean() * this.values.length * this.voxelVolume();
|
|
300
|
+
}
|
|
301
|
+
computeStats() {
|
|
302
|
+
const s = this.values.length;
|
|
303
|
+
let e = 1 / 0, t = -1 / 0, i = 0;
|
|
304
|
+
for (let o = 0; o < s; o++) {
|
|
305
|
+
const a = this.values[o];
|
|
306
|
+
a < e && (e = a), a > t && (t = a), i += a;
|
|
307
|
+
}
|
|
308
|
+
this._min = e, this._max = t, this._mean = i / s, this._invalid = !1;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function F(m) {
|
|
312
|
+
return m.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
238
313
|
}
|
|
239
|
-
function
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
314
|
+
function K(m, s = 6) {
|
|
315
|
+
const e = [], t = B(m);
|
|
316
|
+
e.push("Generated by matsci-parse"), e.push("1.0"), m.lattice.forEach((a) => {
|
|
317
|
+
e.push(a.map((b) => b.toFixed(s)).join(" "));
|
|
243
318
|
});
|
|
244
|
-
const
|
|
245
|
-
new Set(
|
|
246
|
-
),
|
|
247
|
-
(a) =>
|
|
319
|
+
const i = Array.from(
|
|
320
|
+
new Set(m.sites.map((a) => m.species[a.speciesIndex]))
|
|
321
|
+
), o = i.map(
|
|
322
|
+
(a) => m.sites.filter((b) => m.species[b.speciesIndex] === a).length
|
|
248
323
|
);
|
|
249
|
-
return
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
if (
|
|
253
|
-
const
|
|
254
|
-
|
|
324
|
+
return e.push(i.join(" ")), e.push(o.join(" ")), t && e.push("Selective dynamics"), e.push("Cartesian"), i.forEach((a) => {
|
|
325
|
+
m.sites.filter((b) => m.species[b.speciesIndex] === a).forEach((b) => {
|
|
326
|
+
const n = b.cart.map((u) => u.toFixed(s)).join(" ");
|
|
327
|
+
if (t) {
|
|
328
|
+
const h = (Array.isArray(b.props?.selectiveDynamics) ? b.props.selectiveDynamics : [!0, !0, !0]).map((c) => c ? "T" : "F").join(" ");
|
|
329
|
+
e.push(`${n} ${h}`);
|
|
255
330
|
} else
|
|
256
|
-
|
|
331
|
+
e.push(n);
|
|
257
332
|
});
|
|
258
|
-
}),
|
|
333
|
+
}), e.join(`
|
|
259
334
|
`);
|
|
260
335
|
}
|
|
261
|
-
function
|
|
262
|
-
let
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
for (let
|
|
266
|
-
|
|
267
|
-
s
|
|
336
|
+
function Z(m) {
|
|
337
|
+
let s = 0;
|
|
338
|
+
s++;
|
|
339
|
+
const e = parseFloat(m[s++]), t = [];
|
|
340
|
+
for (let c = 0; c < 3; c++)
|
|
341
|
+
t.push(
|
|
342
|
+
m[s++].split(/\s+/).map((l) => parseFloat(l) * e)
|
|
268
343
|
);
|
|
269
|
-
let
|
|
270
|
-
/^[A-Za-z]/.test(
|
|
271
|
-
const a = s
|
|
272
|
-
|
|
273
|
-
let
|
|
274
|
-
s
|
|
275
|
-
const
|
|
276
|
-
return
|
|
277
|
-
for (let
|
|
278
|
-
const r = s
|
|
279
|
-
let
|
|
280
|
-
|
|
281
|
-
r[0] *
|
|
282
|
-
r[0] *
|
|
283
|
-
r[0] *
|
|
284
|
-
] :
|
|
285
|
-
const
|
|
286
|
-
if (
|
|
287
|
-
const
|
|
288
|
-
|
|
344
|
+
let i = m[s].trim(), o;
|
|
345
|
+
/^[A-Za-z]/.test(i) && (o = i.split(/\s+/), s++);
|
|
346
|
+
const a = m[s++].split(/\s+/).map(Number);
|
|
347
|
+
o || (o = a.map((c, l) => `X${l + 1}`));
|
|
348
|
+
let b = !1;
|
|
349
|
+
m[s]?.toLowerCase().startsWith("s") && (b = !0, s++);
|
|
350
|
+
const u = m[s++].toLowerCase().startsWith("d"), h = [];
|
|
351
|
+
return o.forEach((c, l) => {
|
|
352
|
+
for (let f = 0; f < a[l]; f++) {
|
|
353
|
+
const r = m[s++].split(/\s+/).map(Number);
|
|
354
|
+
let p;
|
|
355
|
+
u ? p = [
|
|
356
|
+
r[0] * t[0][0] + r[1] * t[1][0] + r[2] * t[2][0],
|
|
357
|
+
r[0] * t[0][1] + r[1] * t[1][1] + r[2] * t[2][1],
|
|
358
|
+
r[0] * t[0][2] + r[1] * t[1][2] + r[2] * t[2][2]
|
|
359
|
+
] : p = r.slice(0, 3);
|
|
360
|
+
const N = {};
|
|
361
|
+
if (b) {
|
|
362
|
+
const g = r.slice(3, 6).map((_) => _ === 1);
|
|
363
|
+
g.length === 3 && (N.selectiveDynamics = g);
|
|
289
364
|
}
|
|
290
|
-
|
|
365
|
+
h.push(new v(l, p, N));
|
|
291
366
|
}
|
|
292
367
|
}), {
|
|
293
|
-
structure: new
|
|
294
|
-
linesConsumed:
|
|
368
|
+
structure: new I({ lattice: t, species: o, sites: h }),
|
|
369
|
+
linesConsumed: s
|
|
295
370
|
};
|
|
296
371
|
}
|
|
297
|
-
function
|
|
298
|
-
const
|
|
299
|
-
return
|
|
372
|
+
function J(m) {
|
|
373
|
+
const s = F(m);
|
|
374
|
+
return Z(s).structure;
|
|
300
375
|
}
|
|
301
|
-
function
|
|
302
|
-
const
|
|
303
|
-
return
|
|
304
|
-
|
|
305
|
-
}),
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
`${
|
|
376
|
+
function Q(m, s = 6) {
|
|
377
|
+
const e = [];
|
|
378
|
+
return e.push("CRYSTAL"), e.push("PRIMVEC"), m.lattice.forEach((t) => {
|
|
379
|
+
e.push(t.map((i) => i.toFixed(s)).join(" "));
|
|
380
|
+
}), e.push("PRIMCOORD"), e.push(`${m.numSites} 1`), m.sites.forEach((t) => {
|
|
381
|
+
const i = m.species[t.speciesIndex];
|
|
382
|
+
e.push(
|
|
383
|
+
`${i} ${t.cart.map((o) => o.toFixed(s)).join(" ")}`
|
|
309
384
|
);
|
|
310
|
-
}),
|
|
385
|
+
}), e.join(`
|
|
311
386
|
`);
|
|
312
387
|
}
|
|
313
|
-
function
|
|
314
|
-
const
|
|
315
|
-
let
|
|
316
|
-
for (;
|
|
317
|
-
if (
|
|
318
|
-
|
|
319
|
-
for (let
|
|
320
|
-
|
|
321
|
-
for (;
|
|
322
|
-
if (
|
|
323
|
-
|
|
324
|
-
const [a] =
|
|
325
|
-
for (let
|
|
326
|
-
const
|
|
327
|
-
let
|
|
328
|
-
|
|
388
|
+
function ss(m) {
|
|
389
|
+
const s = F(m), e = [], t = [], i = [];
|
|
390
|
+
let o = 0;
|
|
391
|
+
for (; o < s.length && s[o].toUpperCase() !== "PRIMVEC"; ) o++;
|
|
392
|
+
if (o === s.length) throw new Error("PRIMVEC block not found in XSF");
|
|
393
|
+
o++;
|
|
394
|
+
for (let b = 0; b < 3; b++)
|
|
395
|
+
e.push(s[o++].split(/\s+/).map(Number));
|
|
396
|
+
for (; o < s.length && s[o].toUpperCase() !== "PRIMCOORD"; ) o++;
|
|
397
|
+
if (o === s.length) throw new Error("PRIMCOORD block not found in XSF");
|
|
398
|
+
o++;
|
|
399
|
+
const [a] = s[o++].split(/\s+/).map(Number);
|
|
400
|
+
for (let b = 0; b < a; b++) {
|
|
401
|
+
const n = s[o++].split(/\s+/), u = n[0], h = n.slice(1, 4).map(Number);
|
|
402
|
+
let c = t.indexOf(u);
|
|
403
|
+
c === -1 && (t.push(u), c = t.length - 1), i.push(new v(c, h));
|
|
329
404
|
}
|
|
330
|
-
return new
|
|
405
|
+
return new I({ lattice: e, species: t, sites: i });
|
|
331
406
|
}
|
|
332
|
-
function
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
].join(" "),
|
|
407
|
+
function es(m, s = 6) {
|
|
408
|
+
const e = [], t = m.sites.length;
|
|
409
|
+
e.push(String(t));
|
|
410
|
+
const i = B(m), o = m.lattice, a = [
|
|
411
|
+
o[0][0],
|
|
412
|
+
o[1][0],
|
|
413
|
+
o[2][0],
|
|
414
|
+
o[0][1],
|
|
415
|
+
o[1][1],
|
|
416
|
+
o[2][1],
|
|
417
|
+
o[0][2],
|
|
418
|
+
o[1][2],
|
|
419
|
+
o[2][2]
|
|
420
|
+
].join(" "), b = [
|
|
346
421
|
"species:S:1",
|
|
347
422
|
"pos:R:3",
|
|
348
|
-
|
|
423
|
+
i ? "selectiveDynamics:L:3" : null
|
|
349
424
|
].filter(Boolean).join(":");
|
|
350
|
-
|
|
351
|
-
for (const
|
|
352
|
-
const
|
|
353
|
-
let
|
|
354
|
-
if (
|
|
355
|
-
const r = Array.isArray(
|
|
356
|
-
|
|
425
|
+
e.push(`Lattice="${a}" Properties=${b}`);
|
|
426
|
+
for (const n of m.sites) {
|
|
427
|
+
const u = m.species[n.speciesIndex], [h, c, l] = n.cart;
|
|
428
|
+
let f = `${u} ${h.toFixed(s)} ${c.toFixed(s)} ${l.toFixed(s)}`;
|
|
429
|
+
if (i) {
|
|
430
|
+
const r = Array.isArray(n.props?.selectiveDynamics) ? n.props.selectiveDynamics : [!0, !0, !0];
|
|
431
|
+
f += " " + r.map((p) => p ? "T" : "F").join(" ");
|
|
357
432
|
}
|
|
358
|
-
|
|
433
|
+
e.push(f);
|
|
359
434
|
}
|
|
360
|
-
return
|
|
435
|
+
return e.join(`
|
|
361
436
|
`);
|
|
362
437
|
}
|
|
363
|
-
function
|
|
364
|
-
const
|
|
365
|
-
let
|
|
366
|
-
const
|
|
367
|
-
if (!Number.isFinite(
|
|
438
|
+
function ts(m) {
|
|
439
|
+
const s = F(m);
|
|
440
|
+
let e = 0;
|
|
441
|
+
const t = parseInt(s[e++], 10);
|
|
442
|
+
if (!Number.isFinite(t))
|
|
368
443
|
throw new Error("Invalid XYZ: first line must be atom count");
|
|
369
|
-
const
|
|
370
|
-
for (const r of
|
|
371
|
-
let
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
let
|
|
375
|
-
if (
|
|
376
|
-
const r =
|
|
444
|
+
const i = s[e++], o = {}, a = /(\w+)=(".*?"|\S+)/g;
|
|
445
|
+
for (const r of i.matchAll(a)) {
|
|
446
|
+
let p = r[2];
|
|
447
|
+
p.startsWith('"') && (p = p.slice(1, -1)), o[r[1]] = p;
|
|
448
|
+
}
|
|
449
|
+
let b;
|
|
450
|
+
if (o.Lattice) {
|
|
451
|
+
const r = o.Lattice.split(/\s+/).map(Number);
|
|
377
452
|
if (r.length !== 9) throw new Error("Invalid Lattice in extended XYZ");
|
|
378
|
-
|
|
453
|
+
b = [
|
|
379
454
|
[r[0], r[3], r[6]],
|
|
380
455
|
[r[1], r[4], r[7]],
|
|
381
456
|
[r[2], r[5], r[8]]
|
|
382
457
|
];
|
|
383
458
|
} else
|
|
384
459
|
throw new Error("Lattice must be present in extended XYZ format");
|
|
385
|
-
let
|
|
386
|
-
if (
|
|
387
|
-
const r =
|
|
388
|
-
let
|
|
389
|
-
for (let
|
|
390
|
-
const
|
|
391
|
-
|
|
460
|
+
let n = 0, u = 1, h = null;
|
|
461
|
+
if (o.Properties) {
|
|
462
|
+
const r = o.Properties.split(":");
|
|
463
|
+
let p = 0;
|
|
464
|
+
for (let N = 0; N < r.length; N += 3) {
|
|
465
|
+
const g = r[N], _ = parseInt(r[N + 2], 10);
|
|
466
|
+
g === "species" && (n = p), g === "pos" && (u = p), g === "selectiveDynamics" && (h = p), p += _;
|
|
392
467
|
}
|
|
393
468
|
}
|
|
394
|
-
const
|
|
395
|
-
for (let r = 0; r <
|
|
396
|
-
const
|
|
397
|
-
l.has(
|
|
398
|
-
const
|
|
399
|
-
if (
|
|
400
|
-
const
|
|
401
|
-
|
|
469
|
+
const c = [], l = /* @__PURE__ */ new Map(), f = [];
|
|
470
|
+
for (let r = 0; r < t; r++) {
|
|
471
|
+
const p = s[e++].split(/\s+/), N = p[n];
|
|
472
|
+
l.has(N) || (l.set(N, c.length), c.push(N));
|
|
473
|
+
const g = l.get(N), _ = p.slice(u, u + 3).map(Number), S = {};
|
|
474
|
+
if (h !== null) {
|
|
475
|
+
const y = p.slice(h, h + 3).map((d) => d.toUpperCase() === "T");
|
|
476
|
+
y.length === 3 && (S.selectiveDynamics = y);
|
|
402
477
|
}
|
|
403
|
-
|
|
478
|
+
f.push(new v(g, _, S));
|
|
404
479
|
}
|
|
405
|
-
return new
|
|
480
|
+
return new I({ lattice: b, species: c, sites: f });
|
|
406
481
|
}
|
|
407
|
-
function
|
|
408
|
-
return
|
|
482
|
+
function C(m, s) {
|
|
483
|
+
return m[0] * s[0] + m[1] * s[1] + m[2] * s[2];
|
|
409
484
|
}
|
|
410
|
-
function
|
|
411
|
-
return Math.sqrt(
|
|
485
|
+
function L(m) {
|
|
486
|
+
return Math.sqrt(C(m, m));
|
|
412
487
|
}
|
|
413
|
-
function
|
|
414
|
-
return
|
|
488
|
+
function P(m) {
|
|
489
|
+
return m * 180 / Math.PI;
|
|
415
490
|
}
|
|
416
|
-
function
|
|
417
|
-
const [
|
|
418
|
-
if (Math.abs(
|
|
491
|
+
function z(m, s) {
|
|
492
|
+
const [e, t, i] = s, o = e[0] * (t[1] * i[2] - t[2] * i[1]) - e[1] * (t[0] * i[2] - t[2] * i[0]) + e[2] * (t[0] * i[1] - t[1] * i[0]);
|
|
493
|
+
if (Math.abs(o) < 1e-12)
|
|
419
494
|
throw new Error("Singular lattice matrix");
|
|
420
495
|
const a = [
|
|
421
496
|
[
|
|
422
|
-
(
|
|
423
|
-
(
|
|
424
|
-
(
|
|
497
|
+
(t[1] * i[2] - t[2] * i[1]) / o,
|
|
498
|
+
(e[2] * i[1] - e[1] * i[2]) / o,
|
|
499
|
+
(e[1] * t[2] - e[2] * t[1]) / o
|
|
425
500
|
],
|
|
426
501
|
[
|
|
427
|
-
(
|
|
428
|
-
(
|
|
429
|
-
(
|
|
502
|
+
(t[2] * i[0] - t[0] * i[2]) / o,
|
|
503
|
+
(e[0] * i[2] - e[2] * i[0]) / o,
|
|
504
|
+
(e[2] * t[0] - e[0] * t[2]) / o
|
|
430
505
|
],
|
|
431
506
|
[
|
|
432
|
-
(
|
|
433
|
-
(
|
|
434
|
-
(
|
|
507
|
+
(t[0] * i[1] - t[1] * i[0]) / o,
|
|
508
|
+
(e[1] * i[0] - e[0] * i[1]) / o,
|
|
509
|
+
(e[0] * t[1] - e[1] * t[0]) / o
|
|
435
510
|
]
|
|
436
511
|
];
|
|
437
512
|
return [
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
513
|
+
m[0] * a[0][0] + m[1] * a[1][0] + m[2] * a[2][0],
|
|
514
|
+
m[0] * a[0][1] + m[1] * a[1][1] + m[2] * a[2][1],
|
|
515
|
+
m[0] * a[0][2] + m[1] * a[1][2] + m[2] * a[2][2]
|
|
441
516
|
];
|
|
442
517
|
}
|
|
443
|
-
function
|
|
444
|
-
const [
|
|
445
|
-
let
|
|
518
|
+
function ms(m, s = 6) {
|
|
519
|
+
const [e, t, i] = m.lattice, o = L(e), a = L(t), b = L(i), n = P(Math.acos(C(t, i) / (a * b))), u = P(Math.acos(C(e, i) / (o * b))), h = P(Math.acos(C(e, t) / (o * a)));
|
|
520
|
+
let c = `data_made_with_matsci-parse
|
|
446
521
|
_symmetry_space_group_name_H-M 'P 1'
|
|
447
522
|
_symmetry_Int_Tables_number 1
|
|
448
523
|
|
|
449
|
-
_cell_length_a ${
|
|
450
|
-
_cell_length_b ${a.toFixed(
|
|
451
|
-
_cell_length_c ${
|
|
452
|
-
_cell_angle_alpha ${
|
|
453
|
-
_cell_angle_beta ${
|
|
454
|
-
_cell_angle_gamma ${
|
|
524
|
+
_cell_length_a ${o.toFixed(s)}
|
|
525
|
+
_cell_length_b ${a.toFixed(s)}
|
|
526
|
+
_cell_length_c ${b.toFixed(s)}
|
|
527
|
+
_cell_angle_alpha ${n.toFixed(s)}
|
|
528
|
+
_cell_angle_beta ${u.toFixed(s)}
|
|
529
|
+
_cell_angle_gamma ${h.toFixed(s)}
|
|
455
530
|
|
|
456
531
|
loop_
|
|
457
532
|
_atom_site_label
|
|
@@ -460,70 +535,405 @@ function z(s, e = 6) {
|
|
|
460
535
|
_atom_site_fract_y
|
|
461
536
|
_atom_site_fract_z
|
|
462
537
|
`;
|
|
463
|
-
return
|
|
464
|
-
const r =
|
|
465
|
-
|
|
538
|
+
return m.sites.forEach((l, f) => {
|
|
539
|
+
const r = m.species[l.speciesIndex], p = z(l.cart, m.lattice);
|
|
540
|
+
c += `${r}${f + 1} ${r} ${p[0].toFixed(s)} ${p[1].toFixed(
|
|
466
541
|
6
|
|
467
|
-
)} ${
|
|
542
|
+
)} ${p[2].toFixed(s)}
|
|
468
543
|
`;
|
|
469
|
-
}),
|
|
544
|
+
}), c;
|
|
545
|
+
}
|
|
546
|
+
function os(m) {
|
|
547
|
+
const s = F(m);
|
|
548
|
+
let e = 0, t = 0, i = 0, o = 0, a = 0, b = 0, n = [];
|
|
549
|
+
const u = [];
|
|
550
|
+
let h = !1, c = [], l = !1;
|
|
551
|
+
for (const y of s) {
|
|
552
|
+
const d = y.trim();
|
|
553
|
+
if (d) {
|
|
554
|
+
if (d.startsWith("_cell_length_a")) e = parseFloat(d.split(/\s+/)[1]);
|
|
555
|
+
else if (d.startsWith("_cell_length_b"))
|
|
556
|
+
t = parseFloat(d.split(/\s+/)[1]);
|
|
557
|
+
else if (d.startsWith("_cell_length_c"))
|
|
558
|
+
i = parseFloat(d.split(/\s+/)[1]);
|
|
559
|
+
else if (d.startsWith("_cell_angle_alpha"))
|
|
560
|
+
o = parseFloat(d.split(/\s+/)[1]);
|
|
561
|
+
else if (d.startsWith("_cell_angle_beta"))
|
|
562
|
+
a = parseFloat(d.split(/\s+/)[1]);
|
|
563
|
+
else if (d.startsWith("_cell_angle_gamma"))
|
|
564
|
+
b = parseFloat(d.split(/\s+/)[1]);
|
|
565
|
+
else if (d.startsWith("loop_")) {
|
|
566
|
+
h = !0, c = [], l = !1;
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
if (h && d.startsWith("_")) {
|
|
570
|
+
c.push(d), d.includes("_atom_site_") && (l = !0);
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
if (h && !d.startsWith("_")) {
|
|
574
|
+
l && (n.length === 0 && (n = [...c]), u.push(d.split(/\s+/)));
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
if (n.length === 0)
|
|
580
|
+
throw new Error("No _atom_site loop found in CIF");
|
|
581
|
+
const f = k(e, t, i, o, a, b), r = [], p = [], N = n.findIndex((y) => y.includes("fract_x")), g = n.findIndex((y) => y.includes("fract_y")), _ = n.findIndex((y) => y.includes("fract_z")), S = n.findIndex((y) => y.includes("type_symbol"));
|
|
582
|
+
if (N < 0 || g < 0 || _ < 0 || S < 0)
|
|
583
|
+
throw new Error("CIF missing required _atom_site columns");
|
|
584
|
+
for (const y of u) {
|
|
585
|
+
const d = [
|
|
586
|
+
parseFloat(y[N]),
|
|
587
|
+
parseFloat(y[g]),
|
|
588
|
+
parseFloat(y[_])
|
|
589
|
+
], w = U(d, f);
|
|
590
|
+
let x = r.indexOf(y[S]);
|
|
591
|
+
x === -1 && (x = r.length, r.push(y[S])), p.push(new v(x, w));
|
|
592
|
+
}
|
|
593
|
+
return new I({ lattice: f, species: r, sites: p });
|
|
470
594
|
}
|
|
471
|
-
function
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
if (r < 0 || f < 0 || g < 0 || y < 0)
|
|
497
|
-
throw new Error("CIF missing required _atom_site columns");
|
|
498
|
-
for (; p < e.length && e[p].trim() && !e[p].trim().startsWith("_") && !e[p].trim().startsWith("loop_"); ) {
|
|
499
|
-
const _ = e[p].trim().split(/\s+/), S = [
|
|
500
|
-
parseFloat(_[r]),
|
|
501
|
-
parseFloat(_[f]),
|
|
502
|
-
parseFloat(_[g])
|
|
503
|
-
], I = L(
|
|
504
|
-
S,
|
|
505
|
-
T(t, n, o, i, a, c)
|
|
506
|
-
);
|
|
507
|
-
let b = h.indexOf(_[y]);
|
|
508
|
-
b === -1 && (b = h.length, h.push(_[y])), m.push(new x(b, I)), p++;
|
|
509
|
-
}
|
|
595
|
+
function G(m) {
|
|
596
|
+
let s = [];
|
|
597
|
+
const e = [];
|
|
598
|
+
for (let n = 0; n < m.length; n++) {
|
|
599
|
+
const u = m[n].trim();
|
|
600
|
+
if (!(!u || u.startsWith("&")) && /^CELL_PARAMETERS/i.test(u)) {
|
|
601
|
+
let h = 0, c = n + 1;
|
|
602
|
+
for (; h < 3 && c < m.length; ) {
|
|
603
|
+
const l = m[c].trim();
|
|
604
|
+
l !== "" && (s.push(l.split(/\s+/).map(Number)), h++), c++;
|
|
605
|
+
}
|
|
606
|
+
if (h < 3) throw new Error("Incomplete CELL_PARAMETERS block");
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (s.length !== 3)
|
|
611
|
+
throw new Error("CELL_PARAMETERS block not found or incomplete");
|
|
612
|
+
let t = !1, i = "angstrom";
|
|
613
|
+
for (let n = 0; n < m.length; n++) {
|
|
614
|
+
const u = m[n].trim();
|
|
615
|
+
if (!(!u || u.startsWith("&"))) {
|
|
616
|
+
if (/^ATOMIC_POSITIONS/i.test(u)) {
|
|
617
|
+
t = !0;
|
|
618
|
+
const h = u.match(/^ATOMIC_POSITIONS\s+(\w+)/i);
|
|
619
|
+
i = h ? h[1].toLowerCase() : "angstrom";
|
|
510
620
|
continue;
|
|
511
621
|
}
|
|
622
|
+
if (t) {
|
|
623
|
+
const h = u.split(/\s+/);
|
|
624
|
+
if (h.length < 4 || !/^[A-Za-z]/.test(h[0]) || h.slice(1, 4).some((c) => Number.isNaN(Number(c))))
|
|
625
|
+
break;
|
|
626
|
+
e.push(u);
|
|
627
|
+
}
|
|
512
628
|
}
|
|
513
|
-
p++;
|
|
514
629
|
}
|
|
515
|
-
|
|
516
|
-
|
|
630
|
+
if (e.length === 0)
|
|
631
|
+
throw new Error("ATOMIC_POSITIONS block not found");
|
|
632
|
+
const o = i === "crystal", a = [];
|
|
633
|
+
for (const n of e) {
|
|
634
|
+
const u = n.split(/\s+/)[0];
|
|
635
|
+
a.includes(u) || a.push(u);
|
|
636
|
+
}
|
|
637
|
+
const b = [];
|
|
638
|
+
for (const n of e) {
|
|
639
|
+
const u = n.split(/\s+/), h = u[0], c = u.slice(1, 4).map(Number);
|
|
640
|
+
let l;
|
|
641
|
+
o ? l = [
|
|
642
|
+
c[0] * s[0][0] + c[1] * s[1][0] + c[2] * s[2][0],
|
|
643
|
+
c[0] * s[0][1] + c[1] * s[1][1] + c[2] * s[2][1],
|
|
644
|
+
c[0] * s[0][2] + c[1] * s[1][2] + c[2] * s[2][2]
|
|
645
|
+
] : l = c, b.push(new v(a.indexOf(h), l));
|
|
646
|
+
}
|
|
647
|
+
return {
|
|
648
|
+
structure: new I({ lattice: s, species: a, sites: b }),
|
|
649
|
+
linesConsumed: m.length
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
function is(m) {
|
|
653
|
+
const s = F(m);
|
|
654
|
+
return G(s).structure;
|
|
655
|
+
}
|
|
656
|
+
const D = {
|
|
657
|
+
1: { atomicNumber: 1, symbol: "H", name: "Hydrogen", mass: 1.008 },
|
|
658
|
+
2: { atomicNumber: 2, symbol: "He", name: "Helium", mass: 4.0026 },
|
|
659
|
+
3: { atomicNumber: 3, symbol: "Li", name: "Lithium", mass: 6.94 },
|
|
660
|
+
4: { atomicNumber: 4, symbol: "Be", name: "Beryllium", mass: 9.0122 },
|
|
661
|
+
5: { atomicNumber: 5, symbol: "B", name: "Boron", mass: 10.81 },
|
|
662
|
+
6: { atomicNumber: 6, symbol: "C", name: "Carbon", mass: 12.011 },
|
|
663
|
+
7: { atomicNumber: 7, symbol: "N", name: "Nitrogen", mass: 14.007 },
|
|
664
|
+
8: { atomicNumber: 8, symbol: "O", name: "Oxygen", mass: 15.999 },
|
|
665
|
+
9: { atomicNumber: 9, symbol: "F", name: "Fluorine", mass: 18.998 },
|
|
666
|
+
10: { atomicNumber: 10, symbol: "Ne", name: "Neon", mass: 20.18 },
|
|
667
|
+
11: { atomicNumber: 11, symbol: "Na", name: "Sodium", mass: 22.99 },
|
|
668
|
+
12: { atomicNumber: 12, symbol: "Mg", name: "Magnesium", mass: 24.305 },
|
|
669
|
+
13: { atomicNumber: 13, symbol: "Al", name: "Aluminum", mass: 26.982 },
|
|
670
|
+
14: { atomicNumber: 14, symbol: "Si", name: "Silicon", mass: 28.085 },
|
|
671
|
+
15: { atomicNumber: 15, symbol: "P", name: "Phosphorus", mass: 30.974 },
|
|
672
|
+
16: { atomicNumber: 16, symbol: "S", name: "Sulfur", mass: 32.06 },
|
|
673
|
+
17: { atomicNumber: 17, symbol: "Cl", name: "Chlorine", mass: 35.45 },
|
|
674
|
+
18: { atomicNumber: 18, symbol: "Ar", name: "Argon", mass: 39.948 },
|
|
675
|
+
19: { atomicNumber: 19, symbol: "K", name: "Potassium", mass: 39.098 },
|
|
676
|
+
20: { atomicNumber: 20, symbol: "Ca", name: "Calcium", mass: 40.078 },
|
|
677
|
+
21: { atomicNumber: 21, symbol: "Sc", name: "Scandium", mass: 44.956 },
|
|
678
|
+
22: { atomicNumber: 22, symbol: "Ti", name: "Titanium", mass: 47.867 },
|
|
679
|
+
23: { atomicNumber: 23, symbol: "V", name: "Vanadium", mass: 50.942 },
|
|
680
|
+
24: { atomicNumber: 24, symbol: "Cr", name: "Chromium", mass: 51.996 },
|
|
681
|
+
25: { atomicNumber: 25, symbol: "Mn", name: "Manganese", mass: 54.938 },
|
|
682
|
+
26: { atomicNumber: 26, symbol: "Fe", name: "Iron", mass: 55.845 },
|
|
683
|
+
27: { atomicNumber: 27, symbol: "Co", name: "Cobalt", mass: 58.933 },
|
|
684
|
+
28: { atomicNumber: 28, symbol: "Ni", name: "Nickel", mass: 58.693 },
|
|
685
|
+
29: { atomicNumber: 29, symbol: "Cu", name: "Copper", mass: 63.546 },
|
|
686
|
+
30: { atomicNumber: 30, symbol: "Zn", name: "Zinc", mass: 65.38 },
|
|
687
|
+
31: { atomicNumber: 31, symbol: "Ga", name: "Gallium", mass: 69.723 },
|
|
688
|
+
32: { atomicNumber: 32, symbol: "Ge", name: "Germanium", mass: 72.63 },
|
|
689
|
+
33: { atomicNumber: 33, symbol: "As", name: "Arsenic", mass: 74.922 },
|
|
690
|
+
34: { atomicNumber: 34, symbol: "Se", name: "Selenium", mass: 78.971 },
|
|
691
|
+
35: { atomicNumber: 35, symbol: "Br", name: "Bromine", mass: 79.904 },
|
|
692
|
+
36: { atomicNumber: 36, symbol: "Kr", name: "Krypton", mass: 83.798 },
|
|
693
|
+
37: { atomicNumber: 37, symbol: "Rb", name: "Rubidium", mass: 85.468 },
|
|
694
|
+
38: { atomicNumber: 38, symbol: "Sr", name: "Strontium", mass: 87.62 },
|
|
695
|
+
39: { atomicNumber: 39, symbol: "Y", name: "Yttrium", mass: 88.906 },
|
|
696
|
+
40: { atomicNumber: 40, symbol: "Zr", name: "Zirconium", mass: 91.224 },
|
|
697
|
+
41: { atomicNumber: 41, symbol: "Nb", name: "Niobium", mass: 92.906 },
|
|
698
|
+
42: { atomicNumber: 42, symbol: "Mo", name: "Molybdenum", mass: 95.95 },
|
|
699
|
+
43: { atomicNumber: 43, symbol: "Tc", name: "Technetium", mass: 98 },
|
|
700
|
+
44: { atomicNumber: 44, symbol: "Ru", name: "Ruthenium", mass: 101.07 },
|
|
701
|
+
45: { atomicNumber: 45, symbol: "Rh", name: "Rhodium", mass: 102.91 },
|
|
702
|
+
46: { atomicNumber: 46, symbol: "Pd", name: "Palladium", mass: 106.42 },
|
|
703
|
+
47: { atomicNumber: 47, symbol: "Ag", name: "Silver", mass: 107.868 },
|
|
704
|
+
48: { atomicNumber: 48, symbol: "Cd", name: "Cadmium", mass: 112.414 },
|
|
705
|
+
49: { atomicNumber: 49, symbol: "In", name: "Indium", mass: 114.818 },
|
|
706
|
+
50: { atomicNumber: 50, symbol: "Sn", name: "Tin", mass: 118.71 },
|
|
707
|
+
51: { atomicNumber: 51, symbol: "Sb", name: "Antimony", mass: 121.76 },
|
|
708
|
+
52: { atomicNumber: 52, symbol: "Te", name: "Tellurium", mass: 127.6 },
|
|
709
|
+
53: { atomicNumber: 53, symbol: "I", name: "Iodine", mass: 126.904 },
|
|
710
|
+
54: { atomicNumber: 54, symbol: "Xe", name: "Xenon", mass: 131.293 },
|
|
711
|
+
55: { atomicNumber: 55, symbol: "Cs", name: "Cesium", mass: 132.905 },
|
|
712
|
+
56: { atomicNumber: 56, symbol: "Ba", name: "Barium", mass: 137.33 },
|
|
713
|
+
57: { atomicNumber: 57, symbol: "La", name: "Lanthanum", mass: 138.905 },
|
|
714
|
+
58: { atomicNumber: 58, symbol: "Ce", name: "Cerium", mass: 140.12 },
|
|
715
|
+
59: { atomicNumber: 59, symbol: "Pr", name: "Praseodymium", mass: 140.91 },
|
|
716
|
+
60: { atomicNumber: 60, symbol: "Nd", name: "Neodymium", mass: 144.24 },
|
|
717
|
+
61: { atomicNumber: 61, symbol: "Pm", name: "Promethium", mass: 145 },
|
|
718
|
+
62: { atomicNumber: 62, symbol: "Sm", name: "Samarium", mass: 150.36 },
|
|
719
|
+
63: { atomicNumber: 63, symbol: "Eu", name: "Europium", mass: 151.964 },
|
|
720
|
+
64: { atomicNumber: 64, symbol: "Gd", name: "Gadolinium", mass: 157.25 },
|
|
721
|
+
65: { atomicNumber: 65, symbol: "Tb", name: "Terbium", mass: 158.93 },
|
|
722
|
+
66: { atomicNumber: 66, symbol: "Dy", name: "Dysprosium", mass: 162.5 },
|
|
723
|
+
67: { atomicNumber: 67, symbol: "Ho", name: "Holmium", mass: 164.93 },
|
|
724
|
+
68: { atomicNumber: 68, symbol: "Er", name: "Erbium", mass: 167.26 },
|
|
725
|
+
69: { atomicNumber: 69, symbol: "Tm", name: "Thulium", mass: 168.93 },
|
|
726
|
+
70: { atomicNumber: 70, symbol: "Yb", name: "Ytterbium", mass: 173.05 },
|
|
727
|
+
71: { atomicNumber: 71, symbol: "Lu", name: "Lutetium", mass: 174.97 },
|
|
728
|
+
72: { atomicNumber: 72, symbol: "Hf", name: "Hafnium", mass: 178.49 },
|
|
729
|
+
73: { atomicNumber: 73, symbol: "Ta", name: "Tantalum", mass: 180.95 },
|
|
730
|
+
74: { atomicNumber: 74, symbol: "W", name: "Tungsten", mass: 183.84 },
|
|
731
|
+
75: { atomicNumber: 75, symbol: "Re", name: "Rhenium", mass: 186.207 },
|
|
732
|
+
76: { atomicNumber: 76, symbol: "Os", name: "Osmium", mass: 190.23 },
|
|
733
|
+
77: { atomicNumber: 77, symbol: "Ir", name: "Iridium", mass: 192.217 },
|
|
734
|
+
78: { atomicNumber: 78, symbol: "Pt", name: "Platinum", mass: 195.084 },
|
|
735
|
+
79: { atomicNumber: 79, symbol: "Au", name: "Gold", mass: 196.967 },
|
|
736
|
+
80: { atomicNumber: 80, symbol: "Hg", name: "Mercury", mass: 200.592 },
|
|
737
|
+
81: { atomicNumber: 81, symbol: "Tl", name: "Thallium", mass: 204.38 },
|
|
738
|
+
82: { atomicNumber: 82, symbol: "Pb", name: "Lead", mass: 207.2 },
|
|
739
|
+
83: { atomicNumber: 83, symbol: "Bi", name: "Bismuth", mass: 208.98 },
|
|
740
|
+
84: { atomicNumber: 84, symbol: "Po", name: "Polonium", mass: 209 },
|
|
741
|
+
85: { atomicNumber: 85, symbol: "At", name: "Astatine", mass: 210 },
|
|
742
|
+
86: { atomicNumber: 86, symbol: "Rn", name: "Radon", mass: 222 },
|
|
743
|
+
87: { atomicNumber: 87, symbol: "Fr", name: "Francium", mass: 223 },
|
|
744
|
+
88: { atomicNumber: 88, symbol: "Ra", name: "Radium", mass: 226 },
|
|
745
|
+
89: { atomicNumber: 89, symbol: "Ac", name: "Actinium", mass: 227 },
|
|
746
|
+
90: { atomicNumber: 90, symbol: "Th", name: "Thorium", mass: 232.04 },
|
|
747
|
+
91: { atomicNumber: 91, symbol: "Pa", name: "Protactinium", mass: 231.04 },
|
|
748
|
+
92: { atomicNumber: 92, symbol: "U", name: "Uranium", mass: 238.03 },
|
|
749
|
+
93: { atomicNumber: 93, symbol: "Np", name: "Neptunium", mass: 237 },
|
|
750
|
+
94: { atomicNumber: 94, symbol: "Pu", name: "Plutonium", mass: 244 },
|
|
751
|
+
95: { atomicNumber: 95, symbol: "Am", name: "Americium", mass: 243 },
|
|
752
|
+
96: { atomicNumber: 96, symbol: "Cm", name: "Curium", mass: 247 },
|
|
753
|
+
97: { atomicNumber: 97, symbol: "Bk", name: "Berkelium", mass: 247 },
|
|
754
|
+
98: { atomicNumber: 98, symbol: "Cf", name: "Californium", mass: 251 },
|
|
755
|
+
99: { atomicNumber: 99, symbol: "Es", name: "Einsteinium", mass: 252 },
|
|
756
|
+
100: { atomicNumber: 100, symbol: "Fm", name: "Fermium", mass: 257 },
|
|
757
|
+
101: { atomicNumber: 101, symbol: "Md", name: "Mendelevium", mass: 258 },
|
|
758
|
+
102: { atomicNumber: 102, symbol: "No", name: "Nobelium", mass: 259 },
|
|
759
|
+
103: { atomicNumber: 103, symbol: "Lr", name: "Lawrencium", mass: 262 },
|
|
760
|
+
104: { atomicNumber: 104, symbol: "Rf", name: "Rutherfordium", mass: 267 },
|
|
761
|
+
105: { atomicNumber: 105, symbol: "Db", name: "Dubnium", mass: 270 },
|
|
762
|
+
106: { atomicNumber: 106, symbol: "Sg", name: "Seaborgium", mass: 269 },
|
|
763
|
+
107: { atomicNumber: 107, symbol: "Bh", name: "Bohrium", mass: 270 },
|
|
764
|
+
108: { atomicNumber: 108, symbol: "Hs", name: "Hassium", mass: 277 },
|
|
765
|
+
109: { atomicNumber: 109, symbol: "Mt", name: "Meitnerium", mass: 278 },
|
|
766
|
+
110: { atomicNumber: 110, symbol: "Ds", name: "Darmstadtium", mass: 281 },
|
|
767
|
+
111: { atomicNumber: 111, symbol: "Rg", name: "Roentgenium", mass: 282 },
|
|
768
|
+
112: { atomicNumber: 112, symbol: "Cn", name: "Copernicium", mass: 285 },
|
|
769
|
+
113: { atomicNumber: 113, symbol: "Nh", name: "Nihonium", mass: 286 },
|
|
770
|
+
114: { atomicNumber: 114, symbol: "Fl", name: "Flerovium", mass: 289 },
|
|
771
|
+
115: { atomicNumber: 115, symbol: "Mc", name: "Moscovium", mass: 289 },
|
|
772
|
+
116: { atomicNumber: 116, symbol: "Lv", name: "Livermorium", mass: 293 },
|
|
773
|
+
117: { atomicNumber: 117, symbol: "Ts", name: "Tennessine", mass: 294 },
|
|
774
|
+
118: { atomicNumber: 118, symbol: "Og", name: "Oganesson", mass: 294 }
|
|
775
|
+
}, Y = {
|
|
776
|
+
angstrom: 1,
|
|
777
|
+
// canonical
|
|
778
|
+
bohr: 0.529177,
|
|
779
|
+
nm: 10,
|
|
780
|
+
pm: 0.01,
|
|
781
|
+
um: 1e4,
|
|
782
|
+
cm: 1e8,
|
|
783
|
+
m: 1e10,
|
|
784
|
+
fm: 1e-5
|
|
785
|
+
}, q = {
|
|
786
|
+
Å: "angstrom",
|
|
787
|
+
μm: "um"
|
|
788
|
+
}, R = {
|
|
789
|
+
conversions: Y,
|
|
790
|
+
aliases: q,
|
|
791
|
+
convert(m, s, e) {
|
|
792
|
+
const t = (a) => this.aliases[a] ?? a, i = t(s), o = t(e);
|
|
793
|
+
return i === o ? m : m * this.conversions[i] / this.conversions[o];
|
|
794
|
+
},
|
|
795
|
+
convertArray(m, s, e) {
|
|
796
|
+
return m.map((t) => this.convert(t, s, e));
|
|
797
|
+
}
|
|
798
|
+
}, $ = 1.8897268;
|
|
799
|
+
function as(m, s) {
|
|
800
|
+
const e = [];
|
|
801
|
+
e.push("Generated by matsci-parse"), e.push("Volumetric data export");
|
|
802
|
+
const i = [...s.origin].map((l) => l * $);
|
|
803
|
+
e.push(
|
|
804
|
+
`${m.numSites} ${i.map((l) => l.toFixed(6)).join(" ")}`
|
|
805
|
+
);
|
|
806
|
+
const o = s.shape, a = s.basis;
|
|
807
|
+
for (let l = 0; l < 3; l++) {
|
|
808
|
+
a[l];
|
|
809
|
+
const f = a[l].map((r) => r * $);
|
|
810
|
+
e.push(`${o[l]} ${f.map((r) => r.toFixed(6)).join(" ")}`);
|
|
811
|
+
}
|
|
812
|
+
for (const l of m.sites) {
|
|
813
|
+
const f = m.species[l.speciesIndex], r = Object.values(D).find(
|
|
814
|
+
(g) => g.symbol === f
|
|
815
|
+
)?.atomicNumber;
|
|
816
|
+
if (!r)
|
|
817
|
+
throw new Error(`Unknown element symbol: ${f}`);
|
|
818
|
+
[...l.cart];
|
|
819
|
+
const p = l.cart.map((g) => g * $), N = (l.getProp("charge") ?? 0).toFixed(6);
|
|
820
|
+
e.push(
|
|
821
|
+
`${r} ${N} ${p.map((g) => g.toFixed(6)).join(" ")}`
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
const b = s.values, [n, u, h] = o;
|
|
825
|
+
let c = [];
|
|
826
|
+
for (let l = 0; l < h; l++)
|
|
827
|
+
for (let f = 0; f < u; f++)
|
|
828
|
+
for (let r = 0; r < n; r++) {
|
|
829
|
+
const p = s.index(r, f, l);
|
|
830
|
+
c.push(b[p].toExponential(8)), c.length === 6 && (e.push(c.join(" ")), c = []);
|
|
831
|
+
}
|
|
832
|
+
return c.length > 0 && e.push(c.join(" ")), e.join(`
|
|
833
|
+
`);
|
|
834
|
+
}
|
|
835
|
+
function V(m, s = "bohr", e = "bohr", t = "bohr") {
|
|
836
|
+
let i = 0;
|
|
837
|
+
i += 2;
|
|
838
|
+
const o = m[i].split(/\s+/), a = parseInt(o[0]);
|
|
839
|
+
let b = [
|
|
840
|
+
parseFloat(o[1]),
|
|
841
|
+
parseFloat(o[2]),
|
|
842
|
+
parseFloat(o[3])
|
|
843
|
+
];
|
|
844
|
+
i++;
|
|
845
|
+
const n = m[i++].split(/\s+/), u = m[i++].split(/\s+/), h = m[i++].split(/\s+/);
|
|
846
|
+
let c = [
|
|
847
|
+
[parseFloat(n[1]), parseFloat(n[2]), parseFloat(n[3])],
|
|
848
|
+
[parseFloat(u[1]), parseFloat(u[2]), parseFloat(u[3])],
|
|
849
|
+
[
|
|
850
|
+
parseFloat(h[1]),
|
|
851
|
+
parseFloat(h[2]),
|
|
852
|
+
parseFloat(h[3])
|
|
853
|
+
]
|
|
854
|
+
];
|
|
855
|
+
const l = [
|
|
856
|
+
parseInt(n[0], 10),
|
|
857
|
+
parseInt(u[0], 10),
|
|
858
|
+
parseInt(h[0], 10)
|
|
859
|
+
], f = [], r = /* @__PURE__ */ new Map(), p = [];
|
|
860
|
+
for (let w = 0; w < a; w++, i++) {
|
|
861
|
+
const x = m[i].trim().split(/\s+/);
|
|
862
|
+
if (x.length < 5) throw new Error(`Malformed atom line: "${m[i]}"`);
|
|
863
|
+
const A = parseInt(x[0], 10), H = parseFloat(x[1]), W = [
|
|
864
|
+
parseFloat(x[2]),
|
|
865
|
+
parseFloat(x[3]),
|
|
866
|
+
parseFloat(x[4])
|
|
867
|
+
], O = D[A];
|
|
868
|
+
if (!O) throw new Error(`Unknown atomic number: ${A}`);
|
|
869
|
+
const E = O.symbol;
|
|
870
|
+
let T = r.get(E);
|
|
871
|
+
T === void 0 && (T = f.length, f.push(E), r.set(E, T)), p.push(new v(T, W, { charge: H }));
|
|
872
|
+
}
|
|
873
|
+
b = R.convertArray(
|
|
874
|
+
b,
|
|
875
|
+
s,
|
|
876
|
+
"angstrom"
|
|
877
|
+
), c = c.map(
|
|
878
|
+
(w) => R.convertArray(
|
|
879
|
+
w,
|
|
880
|
+
t,
|
|
881
|
+
"angstrom"
|
|
882
|
+
)
|
|
883
|
+
), p.forEach((w) => {
|
|
884
|
+
w.cart = R.convertArray(
|
|
885
|
+
w.cart,
|
|
886
|
+
e,
|
|
887
|
+
"angstrom"
|
|
888
|
+
);
|
|
889
|
+
});
|
|
890
|
+
const N = c.map(
|
|
891
|
+
(w, x) => w.map((A) => A * l[x])
|
|
892
|
+
), g = new I({
|
|
893
|
+
lattice: N,
|
|
894
|
+
species: f,
|
|
895
|
+
sites: p
|
|
896
|
+
}), _ = l[0] * l[1] * l[2], S = new Float32Array(_);
|
|
897
|
+
let y = 0;
|
|
898
|
+
for (; i < m.length && y < _; ) {
|
|
899
|
+
const w = m[i++].trim().split(/\s+/);
|
|
900
|
+
for (const x of w)
|
|
901
|
+
x && y < _ && (S[y] = parseFloat(x), y++);
|
|
902
|
+
}
|
|
903
|
+
if (console.log("numVals", _), y !== _)
|
|
904
|
+
throw new Error(`Cube file truncated: expected ${_}, got ${y}`);
|
|
905
|
+
const d = new X({
|
|
906
|
+
origin: b,
|
|
907
|
+
basis: c,
|
|
908
|
+
shape: l,
|
|
909
|
+
values: S,
|
|
910
|
+
units: "e/ų"
|
|
911
|
+
});
|
|
912
|
+
return { structure: g, volumetricData: d, linesConsumed: i };
|
|
913
|
+
}
|
|
914
|
+
function ns(m) {
|
|
915
|
+
const s = F(m);
|
|
916
|
+
return V(s).volumetricData;
|
|
917
|
+
}
|
|
918
|
+
function rs(m) {
|
|
919
|
+
const s = F(m);
|
|
920
|
+
return V(s).structure;
|
|
517
921
|
}
|
|
518
922
|
export {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
923
|
+
I as CrystalStructure,
|
|
924
|
+
v as Site,
|
|
925
|
+
X as VolumetricData,
|
|
926
|
+
os as cifToStructure,
|
|
927
|
+
rs as cubeToStructure,
|
|
928
|
+
ns as cubeToVolumetric,
|
|
929
|
+
V as parseCube,
|
|
930
|
+
J as poscarToStructure,
|
|
931
|
+
is as pwToStructure,
|
|
932
|
+
ms as structureToCif,
|
|
933
|
+
K as structureToPoscar,
|
|
934
|
+
Q as structureToXsf,
|
|
935
|
+
es as structureToXyz,
|
|
936
|
+
as as volumetricToCube,
|
|
937
|
+
ss as xsfToStructure,
|
|
938
|
+
ts as xyzToStructure
|
|
529
939
|
};
|