matterviz 0.4.0 → 0.4.1
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/brillouin/BrillouinZone.svelte +68 -145
- package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -14
- package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
- package/dist/brillouin/BrillouinZoneScene.svelte +49 -203
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
- package/dist/brillouin/ReciprocalVectors.svelte +39 -0
- package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
- package/dist/brillouin/compute.d.ts +2 -0
- package/dist/brillouin/compute.js +80 -77
- package/dist/brillouin/geometry.d.ts +8 -0
- package/dist/brillouin/geometry.js +57 -0
- package/dist/brillouin/index.d.ts +2 -0
- package/dist/brillouin/index.js +2 -0
- package/dist/brillouin/types.d.ts +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +100 -191
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +176 -464
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
- package/dist/chempot-diagram/color.d.ts +3 -6
- package/dist/chempot-diagram/color.js +5 -5
- package/dist/chempot-diagram/compute.d.ts +3 -3
- package/dist/chempot-diagram/compute.js +3 -1
- package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
- package/dist/chempot-diagram/controls-state.svelte.js +42 -0
- package/dist/chempot-diagram/export.d.ts +47 -0
- package/dist/chempot-diagram/export.js +133 -0
- package/dist/chempot-diagram/index.d.ts +1 -0
- package/dist/chempot-diagram/index.js +1 -0
- package/dist/chempot-diagram/pointer.d.ts +0 -10
- package/dist/chempot-diagram/pointer.js +4 -4
- package/dist/chempot-diagram/types.d.ts +3 -3
- package/dist/colors/index.js +2 -2
- package/dist/composition/FormulaFilter.svelte +6 -5
- package/dist/composition/PieChart.svelte +5 -5
- package/dist/composition/chem-sys.js +3 -2
- package/dist/composition/format.js +3 -2
- package/dist/composition/parse.d.ts +0 -1
- package/dist/composition/parse.js +17 -19
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +0 -1
- package/dist/convex-hull/ConvexHull.svelte +8 -10
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
- package/dist/convex-hull/ConvexHull2D.svelte +94 -175
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +176 -680
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +180 -680
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
- package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
- package/dist/convex-hull/ConvexHullControls.svelte +88 -7
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
- package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
- package/dist/convex-hull/ConvexHullStats.svelte +29 -168
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
- package/dist/convex-hull/barycentric-coords.d.ts +2 -4
- package/dist/convex-hull/barycentric-coords.js +6 -33
- package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
- package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
- package/dist/convex-hull/helpers.d.ts +39 -7
- package/dist/convex-hull/helpers.js +154 -69
- package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
- package/dist/convex-hull/hull-state.svelte.js +124 -0
- package/dist/convex-hull/index.d.ts +9 -7
- package/dist/convex-hull/index.js +7 -2
- package/dist/convex-hull/thermodynamics.js +91 -920
- package/dist/convex-hull/types.d.ts +12 -4
- package/dist/convex-hull/types.js +12 -0
- package/dist/coordination/CoordinationBarPlot.svelte +4 -11
- package/dist/element/BohrAtom.svelte +2 -1
- package/dist/element/ElementTile.svelte.d.ts +1 -1
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +18 -0
- package/dist/feedback/DragOverlay.svelte +3 -1
- package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
- package/dist/feedback/StatusMessage.svelte +13 -3
- package/dist/fermi-surface/FermiSurface.svelte +67 -146
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -224
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
- package/dist/fermi-surface/compute.js +11 -10
- package/dist/fermi-surface/export.js +4 -15
- package/dist/fermi-surface/index.d.ts +0 -1
- package/dist/fermi-surface/index.js +0 -1
- package/dist/fermi-surface/parse.d.ts +1 -1
- package/dist/fermi-surface/parse.js +64 -75
- package/dist/fermi-surface/types.d.ts +2 -2
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +55 -40
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
- package/dist/heatmap-matrix/index.d.ts +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/io/ExportPane.svelte +166 -0
- package/dist/io/ExportPane.svelte.d.ts +17 -0
- package/dist/io/decompress.js +1 -2
- package/dist/io/export.d.ts +5 -1
- package/dist/io/export.js +32 -28
- package/dist/io/fetch.d.ts +2 -1
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +13 -0
- package/dist/io/index.d.ts +2 -0
- package/dist/io/index.js +10 -0
- package/dist/io/types.d.ts +13 -0
- package/dist/isosurface/parse.js +46 -44
- package/dist/labels.js +1 -1
- package/dist/layout/FullscreenButton.svelte +33 -0
- package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
- package/dist/layout/FullscreenToggle.svelte +8 -14
- package/dist/layout/ViewerChrome.svelte +116 -0
- package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
- package/dist/layout/fullscreen.d.ts +4 -0
- package/dist/layout/fullscreen.svelte.d.ts +8 -0
- package/dist/layout/fullscreen.svelte.js +37 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +3 -0
- package/dist/math.d.ts +7 -3
- package/dist/math.js +18 -21
- package/dist/overlays/index.d.ts +4 -0
- package/dist/periodic-table/PeriodicTable.svelte +9 -8
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
- package/dist/phase-diagram/colors.js +1 -1
- package/dist/phase-diagram/parse.d.ts +2 -1
- package/dist/plot/bar/BarPlot.svelte +79 -316
- package/dist/plot/bar/BarPlot.svelte.d.ts +7 -15
- package/dist/plot/bar/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/bar/SpacegroupBarPlot.svelte +2 -1
- package/dist/plot/box/BoxPlot.svelte +76 -246
- package/dist/plot/box/BoxPlot.svelte.d.ts +4 -3
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
- package/dist/plot/box/Violin.svelte.d.ts +1 -1
- package/dist/plot/box/box-plot.d.ts +3 -2
- package/dist/plot/box/box-plot.js +5 -2
- package/dist/plot/box/kde.d.ts +2 -1
- package/dist/plot/box/kde.js +4 -4
- package/dist/plot/core/auto-place.d.ts +1 -1
- package/dist/plot/core/auto-place.js +4 -1
- package/dist/plot/core/components/ColorBar.svelte +5 -5
- package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
- package/dist/plot/core/components/Line.svelte +3 -2
- package/dist/plot/core/components/Line.svelte.d.ts +3 -2
- package/dist/plot/core/components/PlotAxis.svelte +2 -1
- package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
- package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/core/components/ReferenceLine3D.svelte +2 -2
- package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
- package/dist/plot/core/components/ReferencePlane.svelte +2 -2
- package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
- package/dist/plot/core/data-cleaning.js +18 -18
- package/dist/plot/core/fill-utils.d.ts +4 -3
- package/dist/plot/core/fill-utils.js +6 -3
- package/dist/plot/core/interactions.d.ts +5 -1
- package/dist/plot/core/interactions.js +14 -0
- package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
- package/dist/plot/core/pan-zoom.svelte.js +221 -0
- package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -0
- package/dist/plot/core/reference-line.d.ts +10 -10
- package/dist/plot/core/reference-line.js +6 -6
- package/dist/plot/core/scales.d.ts +17 -25
- package/dist/plot/core/scales.js +10 -8
- package/dist/plot/core/svg.d.ts +2 -1
- package/dist/plot/core/types.d.ts +18 -7
- package/dist/plot/core/utils/label-placement.d.ts +1 -1
- package/dist/plot/core/utils/label-placement.js +3 -3
- package/dist/plot/core/utils.d.ts +2 -1
- package/dist/plot/histogram/Histogram.svelte +77 -314
- package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
- package/dist/plot/sankey/Sankey.svelte +2 -5
- package/dist/plot/sankey/Sankey.svelte.d.ts +1 -1
- package/dist/plot/sankey/sankey.js +3 -1
- package/dist/plot/scatter/BinnedScatterPlot.svelte +3 -5
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +4 -4
- package/dist/plot/scatter/ScatterPlot.svelte +160 -450
- package/dist/plot/scatter/ScatterPlot.svelte.d.ts +7 -15
- package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/scatter/binned-scatter-types.d.ts +4 -11
- package/dist/plot/scatter/index.d.ts +1 -1
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte +15 -26
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +9 -10
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +122 -121
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
- package/dist/plot/scatter-3d/Surface3D.svelte +6 -5
- package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
- package/dist/plot/sunburst/Sunburst.svelte +16 -20
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
- package/dist/plot/sunburst/SunburstControls.svelte.d.ts +1 -1
- package/dist/plot/sunburst/sunburst.js +4 -1
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/sanitize.js +13 -2
- package/dist/scene/SceneCamera.svelte +62 -0
- package/dist/scene/SceneCamera.svelte.d.ts +19 -0
- package/dist/scene/bind-renderer.svelte.d.ts +2 -0
- package/dist/scene/bind-renderer.svelte.js +14 -0
- package/dist/scene/index.d.ts +4 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/props.js +52 -0
- package/dist/scene/types.d.ts +26 -0
- package/dist/scene/types.js +1 -0
- package/dist/settings.d.ts +14 -2
- package/dist/settings.js +59 -1
- package/dist/spectral/Bands.svelte +8 -7
- package/dist/spectral/Bands.svelte.d.ts +3 -2
- package/dist/spectral/BandsAndDos.svelte +22 -24
- package/dist/spectral/BrillouinBandsDos.svelte +3 -3
- package/dist/spectral/Dos.svelte +5 -4
- package/dist/spectral/Dos.svelte.d.ts +2 -1
- package/dist/spectral/helpers.d.ts +6 -6
- package/dist/spectral/helpers.js +43 -37
- package/dist/state.svelte.d.ts +0 -7
- package/dist/state.svelte.js +0 -6
- package/dist/structure/Arrow.svelte +2 -4
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CanvasTooltip.svelte +1 -0
- package/dist/structure/CellSelect.svelte +11 -3
- package/dist/structure/CellSelect.svelte.d.ts +2 -1
- package/dist/structure/Lattice.svelte +2 -2
- package/dist/structure/Structure.svelte +291 -355
- package/dist/structure/Structure.svelte.d.ts +5 -15
- package/dist/structure/StructureControls.svelte +217 -2
- package/dist/structure/StructureControls.svelte.d.ts +5 -3
- package/dist/structure/StructureExportPane.svelte +54 -156
- package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
- package/dist/structure/StructureInfoPane.svelte +5 -3
- package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
- package/dist/structure/StructureScene.svelte +365 -198
- package/dist/structure/StructureScene.svelte.d.ts +22 -20
- package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
- package/dist/structure/{label-placement.js → atom-label-placement.js} +12 -2
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +11 -16
- package/dist/structure/bond-order-perception.js +2 -4
- package/dist/structure/bonding.d.ts +3 -0
- package/dist/structure/bonding.js +91 -48
- package/dist/structure/export.d.ts +24 -4
- package/dist/structure/export.js +64 -122
- package/dist/structure/index.d.ts +2 -0
- package/dist/structure/index.js +2 -0
- package/dist/structure/parse.d.ts +3 -2
- package/dist/structure/parse.js +333 -370
- package/dist/structure/partial-occupancy.d.ts +0 -1
- package/dist/structure/partial-occupancy.js +1 -1
- package/dist/structure/pbc.d.ts +1 -1
- package/dist/structure/pbc.js +186 -13
- package/dist/structure/polyhedra.d.ts +41 -0
- package/dist/structure/polyhedra.js +602 -0
- package/dist/structure/site.d.ts +4 -0
- package/dist/structure/site.js +1 -0
- package/dist/structure/supercell.js +3 -2
- package/dist/structure/validation.js +5 -6
- package/dist/symmetry/SymmetryElementControls.svelte +69 -0
- package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
- package/dist/symmetry/SymmetryElements.svelte +354 -0
- package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
- package/dist/symmetry/SymmetryStats.svelte +111 -6
- package/dist/symmetry/WyckoffTable.svelte +68 -7
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
- package/dist/symmetry/cell-transform.js +7 -14
- package/dist/symmetry/index.d.ts +14 -4
- package/dist/symmetry/index.js +301 -80
- package/dist/symmetry/spacegroups.d.ts +5 -1
- package/dist/symmetry/spacegroups.js +15 -1
- package/dist/symmetry/symmetry-elements.d.ts +33 -0
- package/dist/symmetry/symmetry-elements.js +521 -0
- package/dist/symmetry/wyckoff-db.d.ts +9 -0
- package/dist/symmetry/wyckoff-db.js +87 -0
- package/dist/table/HeatmapTable.svelte +4 -15
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/trajectory/Trajectory.svelte +58 -61
- package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
- package/dist/trajectory/TrajectoryExportPane.svelte +15 -24
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +3 -2
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
- package/dist/trajectory/constants.js +6 -2
- package/dist/trajectory/extract.js +17 -37
- package/dist/trajectory/format-detect.d.ts +0 -1
- package/dist/trajectory/format-detect.js +3 -9
- package/dist/trajectory/frame-reader.d.ts +0 -1
- package/dist/trajectory/frame-reader.js +62 -128
- package/dist/trajectory/helpers.d.ts +10 -2
- package/dist/trajectory/helpers.js +56 -36
- package/dist/trajectory/parse/ase.d.ts +9 -1
- package/dist/trajectory/parse/ase.js +47 -32
- package/dist/trajectory/parse/diagnostics.d.ts +3 -0
- package/dist/trajectory/parse/diagnostics.js +14 -0
- package/dist/trajectory/parse/index.d.ts +1 -1
- package/dist/trajectory/parse/index.js +54 -102
- package/dist/trajectory/parse/lammps.d.ts +0 -2
- package/dist/trajectory/parse/lammps.js +8 -6
- package/dist/trajectory/parse/pymatgen.d.ts +2 -0
- package/dist/trajectory/parse/pymatgen.js +74 -0
- package/dist/trajectory/parse/vasp.js +4 -3
- package/dist/trajectory/parse/xyz.d.ts +9 -21
- package/dist/trajectory/parse/xyz.js +28 -33
- package/dist/trajectory/plotting.d.ts +0 -1
- package/dist/trajectory/plotting.js +3 -100
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +1 -1
- package/dist/xrd/XrdPlot.svelte +14 -29
- package/dist/xrd/broadening.d.ts +2 -1
- package/dist/xrd/calc-xrd.js +6 -11
- package/dist/xrd/index.d.ts +2 -2
- package/package.json +29 -16
- package/dist/element/data.json +0 -11864
- package/dist/fermi-surface/marching-cubes.d.ts +0 -2
- package/dist/fermi-surface/marching-cubes.js +0 -2
- package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
- package/dist/plot/core/hover-lock.svelte.js +0 -45
package/dist/structure/pbc.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export declare const wrap_frac_coord: (coord: number) => number;
|
|
|
5
5
|
export declare const wrap_to_unit_cell: (frac: Vec3) => Vec3;
|
|
6
6
|
export declare function find_image_atoms(structure: ParsedStructure, { tolerance }?: {
|
|
7
7
|
tolerance?: number;
|
|
8
|
-
}): [number, Vec3, Vec3][];
|
|
8
|
+
}): [number, Vec3, Vec3, boolean?][];
|
|
9
9
|
export declare function get_pbc_image_sites(...args: Parameters<typeof find_image_atoms>): ParsedStructure;
|
package/dist/structure/pbc.js
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import * as math from '../math';
|
|
2
|
+
import { element_lookup, get_majority_element } from './bonding';
|
|
3
|
+
// Distance slack added to the covalent-radii sum when deciding whether a
|
|
4
|
+
// candidate image atom bonds to a base atom (VESTA-like bond search criterion)
|
|
5
|
+
const BOND_SLACK = 0.4; // Å
|
|
6
|
+
// Below this separation two sites are overlapping copies, not a bond (matches
|
|
7
|
+
// the min_bond_dist default in bonding.ts)
|
|
8
|
+
const MIN_BOND_DIST = 0.4; // Å
|
|
2
9
|
// Wrap a single fractional coordinate to [0, 1), clamping near-1 values to 0
|
|
3
10
|
// and rounding to 15 digits to suppress floating-point noise.
|
|
11
|
+
// NOTE on epsilon: this is the tightest of three intentionally different wrap
|
|
12
|
+
// helpers. Coordinates here come almost straight from file parsing, so float
|
|
13
|
+
// error is tiny and a 1e-10 snap + toFixed(15) preserves maximal precision.
|
|
14
|
+
// Compare wrap_frac @1e-9 [[src/lib/symmetry/index.ts:80]] (post moyo
|
|
15
|
+
// standardization + matrix transforms) and wrap_point @1e-8
|
|
16
|
+
// [[src/lib/symmetry/symmetry-elements.ts:214]] (feeds symmetry-element dedup
|
|
17
|
+
// keys). Do not unify: loosening this epsilon changes snapping near cell
|
|
18
|
+
// boundaries for parsed structures.
|
|
4
19
|
export const wrap_frac_coord = (coord) => {
|
|
5
20
|
const wrapped = coord - Math.floor(coord);
|
|
6
21
|
if (wrapped >= 1 - 1e-10)
|
|
@@ -13,17 +28,23 @@ export const wrap_to_unit_cell = (frac) => [
|
|
|
13
28
|
wrap_frac_coord(frac[1]),
|
|
14
29
|
wrap_frac_coord(frac[2]),
|
|
15
30
|
];
|
|
31
|
+
// Trajectory-like data: >10% of atoms far outside the unit cell. Image-atom
|
|
32
|
+
// generation is skipped for such structures.
|
|
33
|
+
const is_scattered_trajectory = (sites) => {
|
|
34
|
+
const atoms_outside_cell = sites.filter(({ abc }) => abc.some((coord) => coord < -0.1 || coord > 1.1));
|
|
35
|
+
return atoms_outside_cell.length > sites.length * 0.1;
|
|
36
|
+
};
|
|
37
|
+
// Cartesian position of fractional coords abc in the given lattice (rows = lattice vectors)
|
|
38
|
+
const frac_to_cart_pos = (abc, lattice_vecs) => math.add(math.scale(lattice_vecs[0], abc[0]), math.scale(lattice_vecs[1], abc[1]), math.scale(lattice_vecs[2], abc[2]));
|
|
16
39
|
export function find_image_atoms(structure, { tolerance } = {}) {
|
|
17
|
-
// Find image atoms for PBC. Returns [atom_idx, image_xyz, image_abc]
|
|
40
|
+
// Find image atoms for PBC. Returns [atom_idx, image_xyz, image_abc, is_completion?]
|
|
41
|
+
// tuples; is_completion marks phase-2 images that exist only to complete bonds /
|
|
42
|
+
// coordination polyhedra at cell faces (renderers may hide them when neither shows).
|
|
18
43
|
// Skips image generation for trajectory data with scattered atoms.
|
|
19
44
|
if (!structure.lattice || !structure.sites || structure.sites.length === 0)
|
|
20
45
|
return [];
|
|
21
|
-
|
|
22
|
-
const atoms_outside_cell = structure.sites.filter(({ abc }) => abc.some((coord) => coord < -0.1 || coord > 1.1));
|
|
23
|
-
// Skip image generation for trajectory data (>10% atoms outside cell)
|
|
24
|
-
if (atoms_outside_cell.length > structure.sites.length * 0.1) {
|
|
46
|
+
if (is_scattered_trajectory(structure.sites))
|
|
25
47
|
return [];
|
|
26
|
-
}
|
|
27
48
|
// Check if this is a supercell to correctly identify external boundaries correctly
|
|
28
49
|
const image_sites = [];
|
|
29
50
|
const lattice_vecs = structure.lattice.matrix;
|
|
@@ -87,7 +108,7 @@ export function find_image_atoms(structure, { tolerance } = {}) {
|
|
|
87
108
|
img_abc[2] === site.abc[2])
|
|
88
109
|
continue;
|
|
89
110
|
// Compute xyz from img_abc to ensure consistency
|
|
90
|
-
const img_xyz =
|
|
111
|
+
const img_xyz = frac_to_cart_pos(img_abc, lattice_vecs);
|
|
91
112
|
// Skip zero-displacement images (should not happen, guards against FP edge cases)
|
|
92
113
|
const displacement = math.subtract(img_xyz, site.xyz);
|
|
93
114
|
const displacement_len_sq = displacement.reduce((sum, val) => sum + val * val, 0);
|
|
@@ -96,6 +117,156 @@ export function find_image_atoms(structure, { tolerance } = {}) {
|
|
|
96
117
|
image_sites.push([idx, img_xyz, img_abc]);
|
|
97
118
|
}
|
|
98
119
|
}
|
|
120
|
+
// Phase 2: polyhedra-completing images (VESTA boundary-mode-like). The face
|
|
121
|
+
// tolerance above only catches atoms within ~0.5 Å of a boundary, but bonds
|
|
122
|
+
// reach a covalent-radii sum further: an anion just beyond a cell face may be
|
|
123
|
+
// needed to complete the coordination shell of a cation near that face, so
|
|
124
|
+
// bonds and coordination polyhedra at cell edges come out truncated without it.
|
|
125
|
+
// Phase 2 adds ONLY such anion images: a candidate must qualify as a polyhedron
|
|
126
|
+
// vertex (a non-metal/metalloid - same condition as is_anion_vertex in
|
|
127
|
+
// polyhedra.ts) and be strictly more electronegative than the anchor atom it
|
|
128
|
+
// bonds to. Everything else - elemental metals, intermetallics (incl. multi
|
|
129
|
+
// metal ones like Al-Fe-Ni where EN differs but no polyhedra exist), equal-EN
|
|
130
|
+
// covalent networks, cation copies - gets no phase-2 images, so the default
|
|
131
|
+
// render stays minimal and grows uniformly from all cell surfaces (the phase-1
|
|
132
|
+
// boundary copies above are the only non-anion atoms outside the cell).
|
|
133
|
+
const site_radii = [];
|
|
134
|
+
const site_en = [];
|
|
135
|
+
const site_is_metal = [];
|
|
136
|
+
let max_radius = 0;
|
|
137
|
+
// Minimum electronegativity among potential anchors: a candidate can only ever
|
|
138
|
+
// complete some cation's shell if it's strictly more electronegative than this
|
|
139
|
+
let min_anchor_en = Infinity;
|
|
140
|
+
for (const site of structure.sites) {
|
|
141
|
+
const elem = get_majority_element(site);
|
|
142
|
+
const data = elem === null ? undefined : element_lookup.get(elem);
|
|
143
|
+
const radius = data?.covalent_radius ?? null;
|
|
144
|
+
const en = data?.electronegativity ?? null;
|
|
145
|
+
site_radii.push(radius);
|
|
146
|
+
site_en.push(en);
|
|
147
|
+
site_is_metal.push(data?.metal === true);
|
|
148
|
+
if (radius !== null && radius > max_radius)
|
|
149
|
+
max_radius = radius;
|
|
150
|
+
if (radius !== null && en !== null && en < min_anchor_en)
|
|
151
|
+
min_anchor_en = en;
|
|
152
|
+
}
|
|
153
|
+
const max_bond_dist = 2 * max_radius + BOND_SLACK;
|
|
154
|
+
if (max_bond_dist > BOND_SLACK && min_anchor_en < Infinity) {
|
|
155
|
+
// Perpendicular cell heights: |frac| * height lower-bounds the Cartesian
|
|
156
|
+
// distance along each axis (valid for oblique cells)
|
|
157
|
+
const volume = Math.abs(math.dot(lattice_vecs[0], math.cross_3d(lattice_vecs[1], lattice_vecs[2])));
|
|
158
|
+
// height = volume / opposite-face area. A zero-volume (degenerate) cell has two
|
|
159
|
+
// parallel lattice vectors and ill-defined heights; treat every axis as
|
|
160
|
+
// infinitely tall so the pad logic below adds no images (pad -> 0) instead of
|
|
161
|
+
// dividing by zero. When volume > 0 the vectors are linearly independent, so no
|
|
162
|
+
// pairwise cross product can be zero.
|
|
163
|
+
const heights = volume === 0
|
|
164
|
+
? [Infinity, Infinity, Infinity]
|
|
165
|
+
: [
|
|
166
|
+
volume / Math.hypot(...math.cross_3d(lattice_vecs[1], lattice_vecs[2])),
|
|
167
|
+
volume / Math.hypot(...math.cross_3d(lattice_vecs[0], lattice_vecs[2])),
|
|
168
|
+
volume / Math.hypot(...math.cross_3d(lattice_vecs[0], lattice_vecs[1])),
|
|
169
|
+
];
|
|
170
|
+
// Anchor set for the bond test: base atoms plus the phase-1 boundary images
|
|
171
|
+
// (corner/edge/face copies). Anchoring on those too matches VESTA - every
|
|
172
|
+
// displayed boundary cation gets its shell completed (e.g. all 8 corner
|
|
173
|
+
// octahedra in rutile, not just the one at the origin).
|
|
174
|
+
const anchor_positions = structure.sites.map((site) => site.xyz);
|
|
175
|
+
const anchor_radii = [...site_radii];
|
|
176
|
+
const anchor_en = [...site_en];
|
|
177
|
+
for (const [src_idx, img_xyz] of image_sites) {
|
|
178
|
+
anchor_positions.push(img_xyz);
|
|
179
|
+
anchor_radii.push(site_radii[src_idx]);
|
|
180
|
+
anchor_en.push(site_en[src_idx]);
|
|
181
|
+
}
|
|
182
|
+
// Spatial grid over anchors for the bond check
|
|
183
|
+
const grid = new Map();
|
|
184
|
+
const grid_key = (pos) => pos.map((coord) => Math.floor(coord / max_bond_dist)).join(`,`);
|
|
185
|
+
for (const [idx, pos] of anchor_positions.entries()) {
|
|
186
|
+
const key = grid_key(pos);
|
|
187
|
+
const cell = grid.get(key);
|
|
188
|
+
if (cell)
|
|
189
|
+
cell.push(idx);
|
|
190
|
+
else
|
|
191
|
+
grid.set(key, [idx]);
|
|
192
|
+
}
|
|
193
|
+
// True when the candidate (an anion image) bonds a strictly less
|
|
194
|
+
// electronegative anchor, i.e. completes some cation's coordination shell
|
|
195
|
+
const completes_cation_shell = (pos, radius, en) => {
|
|
196
|
+
const [cx, cy, cz] = pos.map((coord) => Math.floor(coord / max_bond_dist));
|
|
197
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
198
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
199
|
+
for (let dz = -1; dz <= 1; dz++) {
|
|
200
|
+
for (const anchor_idx of grid.get(`${cx + dx},${cy + dy},${cz + dz}`) ?? []) {
|
|
201
|
+
const anchor_radius = anchor_radii[anchor_idx];
|
|
202
|
+
const anchor_electroneg = anchor_en[anchor_idx];
|
|
203
|
+
if (anchor_radius === null)
|
|
204
|
+
continue;
|
|
205
|
+
if (anchor_electroneg === null || en <= anchor_electroneg)
|
|
206
|
+
continue;
|
|
207
|
+
const dist = math.euclidean_dist(pos, anchor_positions[anchor_idx]);
|
|
208
|
+
if (dist > MIN_BOND_DIST && dist <= radius + anchor_radius + BOND_SLACK) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
};
|
|
217
|
+
// Dedupe against phase-1 images via (site, integer shift) keys
|
|
218
|
+
const seen_images = new Set(image_sites.map(([idx, _xyz, img_abc]) => `${idx}|${img_abc
|
|
219
|
+
.map((coord, axis) => Math.round(coord - structure.sites[idx].abc[axis]))
|
|
220
|
+
.join(`,`)}`));
|
|
221
|
+
for (const [idx, site] of structure.sites.entries()) {
|
|
222
|
+
const radius = site_radii[idx];
|
|
223
|
+
const en = site_en[idx];
|
|
224
|
+
// Skip candidates that could never be a polyhedron vertex: metals (e.g.
|
|
225
|
+
// Fe/Ni in Al-Fe-Ni intermetallics, despite their higher EN) and anything
|
|
226
|
+
// not strictly more electronegative than at least one anchor (covers all
|
|
227
|
+
// sites of elemental/equal-EN structures and all cations)
|
|
228
|
+
if (radius === null || en === null || en <= min_anchor_en)
|
|
229
|
+
continue;
|
|
230
|
+
if (site_is_metal[idx])
|
|
231
|
+
continue;
|
|
232
|
+
// Per-axis shifts that could land a copy of this atom within bonding reach
|
|
233
|
+
// of the cell: {0} plus +1/-1 when the atom is within max_bond_dist of the
|
|
234
|
+
// respective boundary
|
|
235
|
+
const axis_shifts = [0, 1, 2].map((axis) => {
|
|
236
|
+
if (!pbc[axis])
|
|
237
|
+
return [0];
|
|
238
|
+
// + face tolerance: anchors (phase-1 images) can sit slightly outside the cell
|
|
239
|
+
const pad = (max_bond_dist + PHYSICAL_TOLERANCE) / heights[axis];
|
|
240
|
+
const shifts = [0];
|
|
241
|
+
if (site.abc[axis] < pad)
|
|
242
|
+
shifts.push(1);
|
|
243
|
+
if (site.abc[axis] > 1 - pad)
|
|
244
|
+
shifts.push(-1);
|
|
245
|
+
return shifts;
|
|
246
|
+
});
|
|
247
|
+
for (const shift_a of axis_shifts[0]) {
|
|
248
|
+
for (const shift_b of axis_shifts[1]) {
|
|
249
|
+
for (const shift_c of axis_shifts[2]) {
|
|
250
|
+
if (shift_a === 0 && shift_b === 0 && shift_c === 0)
|
|
251
|
+
continue;
|
|
252
|
+
const key = `${idx}|${shift_a},${shift_b},${shift_c}`;
|
|
253
|
+
if (seen_images.has(key))
|
|
254
|
+
continue;
|
|
255
|
+
const img_abc = [
|
|
256
|
+
site.abc[0] + shift_a,
|
|
257
|
+
site.abc[1] + shift_b,
|
|
258
|
+
site.abc[2] + shift_c,
|
|
259
|
+
];
|
|
260
|
+
const img_xyz = frac_to_cart_pos(img_abc, lattice_vecs);
|
|
261
|
+
if (!completes_cation_shell(img_xyz, radius, en))
|
|
262
|
+
continue;
|
|
263
|
+
seen_images.add(key);
|
|
264
|
+
image_sites.push([idx, img_xyz, img_abc, true]);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
99
270
|
return image_sites;
|
|
100
271
|
}
|
|
101
272
|
// Return structure with image atoms added
|
|
@@ -104,23 +275,25 @@ export function get_pbc_image_sites(...args) {
|
|
|
104
275
|
if (!structure || !structure.sites || structure.sites.length === 0) {
|
|
105
276
|
return structure;
|
|
106
277
|
}
|
|
107
|
-
// Check for trajectory data
|
|
108
|
-
const atoms_outside_cell = structure.sites.filter((site) => site.abc.some((coord) => coord < -0.1 || coord > 1.1));
|
|
109
278
|
// Return trajectory data unchanged
|
|
110
|
-
if (
|
|
279
|
+
if (is_scattered_trajectory(structure.sites))
|
|
111
280
|
return structure;
|
|
112
|
-
}
|
|
113
281
|
// Add image atoms to regular crystal structures
|
|
114
282
|
const image_sites = find_image_atoms(...args);
|
|
115
283
|
const imaged_struct = { ...structure, sites: [...structure.sites] };
|
|
116
284
|
// Add image atoms as new sites using provided (xyz, abc) from find_image_atoms
|
|
117
|
-
for (const [site_idx, img_xyz, img_abc] of image_sites) {
|
|
285
|
+
for (const [site_idx, img_xyz, img_abc, is_completion] of image_sites) {
|
|
118
286
|
const orig_site = structure.sites[site_idx];
|
|
119
287
|
imaged_struct.sites.push({
|
|
120
288
|
...orig_site,
|
|
121
289
|
abc: img_abc,
|
|
122
290
|
xyz: img_xyz,
|
|
123
|
-
properties: {
|
|
291
|
+
properties: {
|
|
292
|
+
...orig_site.properties,
|
|
293
|
+
orig_site_idx: site_idx,
|
|
294
|
+
// phase-2 images only complete bonds/polyhedra - hidden when neither renders
|
|
295
|
+
...(is_completion ? { completion_image: true } : {}),
|
|
296
|
+
},
|
|
124
297
|
});
|
|
125
298
|
}
|
|
126
299
|
return imaged_struct;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ElementSymbol } from '../element';
|
|
2
|
+
import type { Vec3 } from '../math';
|
|
3
|
+
import type { AnyStructure, BondPair } from './';
|
|
4
|
+
export type PolyhedraColorMode = `vertex` | `center` | `uniform`;
|
|
5
|
+
export interface PolyhedraOptions {
|
|
6
|
+
min_neighbors?: number;
|
|
7
|
+
max_neighbors?: number;
|
|
8
|
+
excluded_center_elements?: readonly string[];
|
|
9
|
+
included_center_elements?: readonly string[];
|
|
10
|
+
electronegativity_margin?: number;
|
|
11
|
+
distance_factor?: number;
|
|
12
|
+
weak_bond_norm?: number;
|
|
13
|
+
volume_eps?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ConvexHullResult {
|
|
16
|
+
vertices: Vec3[];
|
|
17
|
+
input_idxs: number[];
|
|
18
|
+
faces: [number, number, number][];
|
|
19
|
+
volume: number;
|
|
20
|
+
}
|
|
21
|
+
export interface Polyhedron {
|
|
22
|
+
center_site_idx: number;
|
|
23
|
+
center_orig_idx: number;
|
|
24
|
+
center_element: ElementSymbol;
|
|
25
|
+
vertices: Vec3[];
|
|
26
|
+
vertex_site_idxs: number[];
|
|
27
|
+
faces: [number, number, number][];
|
|
28
|
+
volume: number;
|
|
29
|
+
}
|
|
30
|
+
export interface MergedPolyhedraBuffers {
|
|
31
|
+
positions: Float32Array;
|
|
32
|
+
colors: Float32Array;
|
|
33
|
+
edge_positions: Float32Array;
|
|
34
|
+
triangle_count: number;
|
|
35
|
+
edge_count: number;
|
|
36
|
+
}
|
|
37
|
+
export declare function convex_hull_3d(points: readonly Vec3[], eps_scale?: number): ConvexHullResult;
|
|
38
|
+
export declare function build_adjacency(bonds: readonly BondPair[]): Map<number, Set<number>>;
|
|
39
|
+
export declare const is_spectator_center: (element: string) => boolean;
|
|
40
|
+
export declare function compute_polyhedra(structure: AnyStructure, bonds: readonly BondPair[], options?: PolyhedraOptions): Polyhedron[];
|
|
41
|
+
export declare function merge_polyhedra_buffers(polyhedra: readonly Polyhedron[], get_vertex_color: (poly: Polyhedron, vertex_idx: number) => string, coplanar_tol?: number): MergedPolyhedraBuffers;
|