1- export to_xyz
1+ export to_xyz, to_ucposcar, to_ssposcar
22
33function 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)
25115end
0 commit comments