Skip to content

Commit baa02fb

Browse files
authored
Merge pull request #5 from ejmeitz/ucposcar
add IO for uc and ssposcar
2 parents 15dcc16 + 041aa3f commit baa02fb

File tree

4 files changed

+99
-3
lines changed

4 files changed

+99
-3
lines changed

Project.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
name = "SimpleCrystals"
22
uuid = "64031d72-e220-11ed-1a7e-43a2532b2fa8"
33
authors = ["Ethan Meitz <emeitz@andrew.cmu.edu>"]
4-
version = "0.4.0"
4+
version = "0.4.1"
55

66
[deps]
77
AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a"
88
PeriodicTable = "7b2266bf-644c-5ea3-82d8-af4bbd25a884"
9+
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
910
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1011
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1112
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
1213

1314
[compat]
1415
AtomsBase = "0.5"
1516
PeriodicTable = "1.1"
17+
Printf = "1.11.0"
1618
Reexport = "1"
1719
StaticArrays = "1.5.17"
1820
Unitful = "1"
19-
julia = "1.7,1.10"
21+
julia = "1.10"

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,6 @@ for atom in fcc_crystal
140140
#do something
141141
end
142142
```
143+
144+
There are also functions `to_ucposcar` and `to_ssposcar` to generate poscar files. If your crystal
145+
does not use Unitful ensure your positions and lattice vectors are in Angstroms.

src/FileWriter.jl

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export to_xyz
1+
export to_xyz, to_ucposcar, to_ssposcar
22

33
function to_xyz(crystal::Crystal{3}, outpath)
44
N_atoms = length(crystal)
@@ -22,4 +22,94 @@ function to_xyz(crystal::Crystal{2}, outpath)
2222
println(file,"$(string(atomic_symbol(atom))) $(ustrip(atom.position[1])) $(ustrip(atom.position[2]))")
2323
end
2424
close(file)
25+
end
26+
27+
"""
28+
cartesian_to_fractional(latt::BravaisLattice{3}, x::AbstractVector) where T
29+
30+
Convert a Cartesian coordinate `x` into fractional coordinates w.r.t. the
31+
primitive vectors of `latt`.
32+
"""
33+
cartesian_to_fractional(lattice_vectors::AbstractMatrix, x::AbstractVector) = lattice_vectors \ x
34+
35+
36+
function convert_to_ang_and_strip(x)
37+
if eltype(x) <: Unitful.Length
38+
x = ustrip.(u"Å", x)
39+
else
40+
@error "Expected length units, got $(unit(first(x)))"
41+
end
42+
end
43+
44+
function write_poscar(cryst::Crystal{D}, cell::AbstractMatrix, path::AbstractString) where D
45+
# 1) collect element order & counts
46+
all_syms = [atomic_symbol(atom) for atom in cryst.atoms]
47+
# preserve order of first appearance in basis
48+
order = unique([atomic_symbol(atom) for atom in cryst.basis])
49+
counts = [count(==(sym), all_syms) for sym in order]
50+
51+
open(path, "w") do io
52+
println(io, "POSCAR") # comment line
53+
println(io, "1.0") # universal scale
54+
55+
# primitive vectors as rows
56+
for i in 1:D
57+
v = convert_to_ang_and_strip(cell[:,i])
58+
for el in v
59+
@printf(io, "%.15f ", el)
60+
end
61+
println(io)
62+
end
63+
64+
# elements and counts
65+
println(io, join(order, " "))
66+
println(io, join(counts, " "))
67+
68+
println(io, "Direct") # fractional coords
69+
70+
# write atoms in block order
71+
for sym in order
72+
for atom in cryst.atoms
73+
if atomic_symbol(atom) == sym
74+
x = convert_to_ang_and_strip(position(atom))
75+
vec = convert_to_ang_and_strip(cell)
76+
x_frac = cartesian_to_fractional(vec, x)
77+
for el in x_frac
78+
@printf(io, "%.15f ", el)
79+
end
80+
println(io)
81+
end
82+
end
83+
end
84+
end
85+
end
86+
87+
"""
88+
to_ucposcar(cryst::Crystal{3}; filename="ucposcar")
89+
90+
Automatically extracts the *unit cell* from `cryst` (i.e. N_unit_cells ≡ (1,1,1))
91+
and writes it to a POSCAR-style file named `filename`.
92+
"""
93+
function to_ucposcar(cryst::Crystal{D}, filename::AbstractString="ucposcar") where D
94+
95+
n_cells = @SVector ones(Int, D)
96+
97+
uc = Crystal(
98+
cryst.lattice,
99+
cryst.basis,
100+
n_cells,
101+
cryst.basis
102+
)
103+
write_poscar(uc, cryst.lattice.primitive_vectors, filename)
104+
end
105+
106+
"""
107+
supercell(cryst::Crystal{3}; filename="ssposcar")
108+
109+
Writes the full supercell defined by `cryst.N_unit_cells` to a
110+
POSCAR-style file named `filename`.
111+
"""
112+
function to_ssposcar(cryst::Crystal, filename::AbstractString="ssposcar")
113+
cell = cryst.lattice.primitive_vectors .* cryst.N_unit_cells
114+
write_poscar(cryst, cell, filename)
25115
end

src/SimpleCrystals.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module SimpleCrystals
22

33
using Reexport
44
using PeriodicTable
5+
using Printf
56

67
@reexport using AtomsBase
78
@reexport using Unitful

0 commit comments

Comments
 (0)