Skip to content

Commit

Permalink
add function find_image_atoms() used in StructureScene to draw images…
Browse files Browse the repository at this point in the history
… of atoms

near opposite side of unit cell

with fractional tolerance for proximity to cell as option
also add unit test and fixtures for find_image_atoms()
  • Loading branch information
janosh committed Jun 28, 2023
1 parent 142effb commit 3098d6c
Show file tree
Hide file tree
Showing 7 changed files with 529 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/lib/StructureScene.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import { pretty_num } from './labels'
import { element_colors } from './stores'
import type { PymatgenStructure, Site } from './structure'
import { atomic_radii, euclidean_dist } from './structure'
import { atomic_radii, euclidean_dist, find_image_atoms } from './structure'
// output of pymatgen.core.Structure.as_dict()
export let structure: PymatgenStructure | undefined = undefined
Expand Down Expand Up @@ -79,8 +79,8 @@
{@const radius = (same_size_atoms ? 1 : atomic_radii[elem]) * atom_radius}
<T.SphereGeometry args={[radius, 20, 20]} />
<T.MeshStandardMaterial />
{#each structure.sites as site, idx}
{@const { xyz, species } = site}
{#each find_image_atoms(structure) as [site_idx, xyz], idx}
{@const { species } = structure.sites[site_idx]}
<Instance
position={xyz}
color={$element_colors[species[0].element]}
Expand Down
50 changes: 50 additions & 0 deletions src/lib/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,53 @@ export function euclidean_dist(p1: Vector, p2: Vector): number {
const dz = p1[2] - p2[2]
return Math.sqrt(dx * dx + dy * dy + dz * dz)
}

function generate_permutations(length: number): number[][] {
const result: number[][] = []
for (let i = 0; i < Math.pow(2, length); i++) {
const binaryString = i.toString(2).padStart(length, `0`)
result.push(Array.from(binaryString).map(Number))
}
return result
}

export function find_image_atoms(
structure: PymatgenStructure,
{ tolerance = 0.05 }: { tolerance?: number } = {}
// fractional tolerance for determining if a site is at the edge of the unit cell
): Array<[number, Vector]> {
const edge_sites: Array<[number, Vector]> = []
const permutations = generate_permutations(3)

structure.sites.forEach((site, idx) => {
const abc = site.abc
const xyz = site.xyz

edge_sites.push([idx, xyz])

// Check if the site is at the edge and determine its image
const edges: number[] = [0, 1, 2].filter(
(i) => Math.abs(abc[i]) < tolerance || Math.abs(abc[i] - 1) < tolerance
)

const { a, b, c } = structure.lattice
if (edges.length > 0) {
for (const perm of permutations) {
const img_xyz: Vector = xyz.slice()
for (const [idx, edge] of edges.entries()) {
if (perm[idx] === 1) {
// Image atom at the opposite edge
if (Math.abs(abc[edge]) < tolerance) {
img_xyz[edge] += edge === 0 ? a : edge === 1 ? b : c
} else {
img_xyz[edge] -= edge === 0 ? a : edge === 1 ? b : c
}
}
}
edge_sites.push([idx, img_xyz])
}
}
})

return edge_sites
}
12 changes: 12 additions & 0 deletions tests/unit/fixtures/find_image_atoms/mp-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
[0, [0, 0, 0]],
[0, [0, 0, 0]],
[0, [0, 0, 6.256930122878799]],
[0, [0, 6.256930122878799, 0]],
[0, [0, 6.256930122878799, 6.256930122878799]],
[0, [6.256930122878799, 0, 0]],
[0, [6.256930122878799, 0, 6.256930122878799]],
[0, [6.256930122878799, 6.256930122878799, 0]],
[0, [6.256930122878799, 6.256930122878799, 6.256930122878799]],
[1, [3.1284650614394, 3.1284650614393996, 3.1284650614394]]
]
50 changes: 50 additions & 0 deletions tests/unit/fixtures/find_image_atoms/mp-1234.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
[0, [6.201186995551753e-16, 3.8561654465837516, 2.3612203355707076e-16]],
[0, [6.201186995551753e-16, 3.8561654465837516, 2.3612203355707076e-16]],
[0, [6.201186995551753e-16, 3.8561654465837516, 2.3612203355707076e-16]],
[0, [6.201186995551753e-16, 3.8561654465837516, 7.712330893167503]],
[0, [6.201186995551753e-16, 3.8561654465837516, 7.712330893167503]],
[0, [7.712330893167504, 3.8561654465837516, 2.3612203355707076e-16]],
[0, [7.712330893167504, 3.8561654465837516, 2.3612203355707076e-16]],
[0, [7.712330893167504, 3.8561654465837516, 7.712330893167503]],
[0, [7.712330893167504, 3.8561654465837516, 7.712330893167503]],
[1, [5.784248169875627, 1.9280827232918758, 1.9280827232918762]],
[2, [0, 0, 3.8561654465837516]],
[2, [0, 0, 3.8561654465837516]],
[2, [0, 0, 3.8561654465837516]],
[2, [0, 7.712330893167503, 3.8561654465837516]],
[2, [0, 7.712330893167503, 3.8561654465837516]],
[2, [7.712330893167503, 0, 3.8561654465837516]],
[2, [7.712330893167503, 0, 3.8561654465837516]],
[2, [7.712330893167503, 7.712330893167503, 3.8561654465837516]],
[2, [7.712330893167503, 7.712330893167503, 3.8561654465837516]],
[3, [5.784248169875628, 5.784248169875627, 5.784248169875628]],
[4, [3.856165446583752, 3.8561654465837516, 3.856165446583752]],
[5, [1.928082723291876, 1.9280827232918758, 5.784248169875628]],
[6, [3.8561654465837516, 0, 2.3612203355707076e-16]],
[6, [3.8561654465837516, 0, 2.3612203355707076e-16]],
[6, [3.8561654465837516, 0, 2.3612203355707076e-16]],
[6, [3.8561654465837516, 0, 7.712330893167503]],
[6, [3.8561654465837516, 0, 7.712330893167503]],
[6, [3.8561654465837516, 7.712330893167503, 2.3612203355707076e-16]],
[6, [3.8561654465837516, 7.712330893167503, 2.3612203355707076e-16]],
[6, [3.8561654465837516, 7.712330893167503, 7.712330893167503]],
[6, [3.8561654465837516, 7.712330893167503, 7.712330893167503]],
[7, [1.9280827232918767, 5.784248169875627, 1.9280827232918762]],
[8, [0.964041361645938, 0.9640413616459379, 0.964041361645938]],
[9, [4.82020680822969, 2.8921240849378136, 6.748289531521566]],
[10, [6.748289531521565, 0.9640413616459379, 6.748289531521566]],
[11, [2.892124084937814, 2.8921240849378136, 0.9640413616459382]],
[12, [0.9640413616459387, 4.820206808229689, 4.82020680822969]],
[13, [4.82020680822969, 6.748289531521565, 2.8921240849378145]],
[14, [6.748289531521566, 4.820206808229689, 2.8921240849378145]],
[15, [2.8921240849378145, 6.748289531521565, 4.82020680822969]],
[16, [4.820206808229689, 0.9640413616459379, 4.82020680822969]],
[17, [0.9640413616459383, 2.8921240849378136, 2.892124084937814]],
[18, [2.8921240849378136, 0.9640413616459379, 2.892124084937814]],
[19, [6.748289531521566, 2.8921240849378136, 4.82020680822969]],
[20, [4.82020680822969, 4.820206808229689, 0.9640413616459385]],
[21, [0.964041361645939, 6.748289531521565, 6.748289531521566]],
[22, [2.8921240849378145, 4.820206808229689, 6.748289531521566]],
[23, [6.748289531521566, 6.748289531521565, 0.9640413616459387]]
]
38 changes: 38 additions & 0 deletions tests/unit/fixtures/find_image_atoms/mp-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[
[0, [0, 0, 0]],
[0, [0, 0, 0]],
[0, [0, 0, 3.9173015749846063]],
[0, [0, 3.9173015749846063, 0]],
[0, [0, 3.9173015749846063, 3.9173015749846063]],
[0, [3.9173015749846063, 0, 0]],
[0, [3.9173015749846063, 0, 3.9173015749846063]],
[0, [3.9173015749846063, 3.9173015749846063, 0]],
[0, [3.9173015749846063, 3.9173015749846063, 3.9173015749846063]],
[1, [3.149750694173353e-16, 1.9586507874923031, 1.9586507874923034]],
[1, [3.149750694173353e-16, 1.9586507874923031, 1.9586507874923034]],
[1, [3.149750694173353e-16, 1.9586507874923031, 1.9586507874923034]],
[1, [3.149750694173353e-16, 1.9586507874923031, 1.9586507874923034]],
[1, [3.149750694173353e-16, 1.9586507874923031, 1.9586507874923034]],
[1, [3.9173015749846067, 1.9586507874923031, 1.9586507874923034]],
[1, [3.9173015749846067, 1.9586507874923031, 1.9586507874923034]],
[1, [3.9173015749846067, 1.9586507874923031, 1.9586507874923034]],
[1, [3.9173015749846067, 1.9586507874923031, 1.9586507874923034]],
[2, [1.9586507874923031, 0, 1.9586507874923034]],
[2, [1.9586507874923031, 0, 1.9586507874923034]],
[2, [1.9586507874923031, 0, 1.9586507874923034]],
[2, [1.9586507874923031, 0, 1.9586507874923034]],
[2, [1.9586507874923031, 0, 1.9586507874923034]],
[2, [1.9586507874923031, 3.9173015749846063, 1.9586507874923034]],
[2, [1.9586507874923031, 3.9173015749846063, 1.9586507874923034]],
[2, [1.9586507874923031, 3.9173015749846063, 1.9586507874923034]],
[2, [1.9586507874923031, 3.9173015749846063, 1.9586507874923034]],
[3, [1.9586507874923034, 1.9586507874923031, 2.3986554175498917e-16]],
[3, [1.9586507874923034, 1.9586507874923031, 2.3986554175498917e-16]],
[3, [1.9586507874923034, 1.9586507874923031, 2.3986554175498917e-16]],
[3, [1.9586507874923034, 1.9586507874923031, 2.3986554175498917e-16]],
[3, [1.9586507874923034, 1.9586507874923031, 2.3986554175498917e-16]],
[3, [1.9586507874923034, 1.9586507874923031, 3.9173015749846067]],
[3, [1.9586507874923034, 1.9586507874923031, 3.9173015749846067]],
[3, [1.9586507874923034, 1.9586507874923031, 3.9173015749846067]],
[3, [1.9586507874923034, 1.9586507874923031, 3.9173015749846067]]
]

0 comments on commit 3098d6c

Please sign in to comment.