Handling Atoms

This package makes the choice to separate the atomic parameters from their positions and velocities for ease of use with the differential equations solvers. This contrasts somewhat with most other software packages where these would be usually by joined together into a single object.

The atomic parameters here are contained within the Atoms type introduced earlier in the Getting started section. As mentioned previously, there exist some basic constructors which use either elemental symbols or numbers to initialise the parameters:

julia> using NQCDynamics
julia> Atoms([:H, :H, :H])Atoms{Float64}([:H, :H, :H], [1, 1, 1], [1837.4715941070515, 1837.4715941070515, 1837.4715941070515])
julia> Atoms([1, 2, 3])Atoms{Float64}([:X, :X, :X], [0, 0, 0], [1.0, 2.0, 3.0])

If there are many atoms, you can use Julia's array manipulation utilities to create large vectors with many atoms types. For example, if adding an adsorbate to a metal surface, it could be initialised as:

julia> au = fill(:Au, 40)40-element Vector{Symbol}:
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 ⋮
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
 :Au
julia> no = [:N, :O]2-element Vector{Symbol}: :N :O
julia> auno = [au; no]42-element Vector{Symbol}: :Au :Au :Au :Au :Au :Au :Au :Au :Au :Au ⋮ :Au :Au :Au :Au :Au :Au :Au :N :O
julia> Atoms(auno)Atoms{Float64}([:Au, :Au, :Au, :Au, :Au, :Au, :Au, :Au, :Au, :Au … :Au, :Au, :Au, :Au, :Au, :Au, :Au, :Au, :N, :O], [79, 79, 79, 79, 79, 79, 79, 79, 79, 79 … 79, 79, 79, 79, 79, 79, 79, 79, 7, 8], [359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164 … 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 359048.0926227164, 25533.199026445902, 29164.39289099079])

Manipulating atomic structures with AtomsBase.jl

AtomsBase provides a convenient format for representing atomic geometries, facilitating interoperability between a collection of different packages.

When working with NQCDynamics, the most useful packages are AtomsIO for reading and writing structures and trajectories, and ASEconvert for working with ASE from within Julia.

Using ASE with ASEconvert.jl

This example shows how ASEconvert can be used to build a structure, then convert from the ASE format into an AtomsBase compatible system:

using ASEconvert

# Make a silicon supercell using ASE
atoms_ase = ase.build.bulk("Si") * pytuple((4, 1, 1))

# Convert to an AtomsBase-compatible structure
atoms_ab = pyconvert(AbstractSystem, atoms_ase)

It is currently not possible to use an AtomsBase system directly with NQCDynamics, but can be quickly converted to the correct format:

using NQCDynamics
atoms_nqcd = Atoms(atoms_ab)
r = Position(atoms_ab)
v = Velocity(atoms_ab)
c = Cell(atoms_ab)

Saving and loading with AtomsIO.jl

After running a simulation it often desirable to save the trajectory in a standard format for visualization. For this, convert the NQCDynamics output into the AtomsBase format, then use AtomsIO to write the file in your chosen format.

using AtomsIO

system = System(atoms_nqcd, r, v, c)

AtomsIO.save_system("Si.xyz", system) # Save a single image

trajectory = Trajectory(atoms_nqcd, [r, r, r, r], [v, v, v, v], c)
AtomsIO.save_trajectory("Si.xyz", trajectory) # Save a trajectory

AtomsIO also provides load_system and load_trajectory which can be converted to the NQCDynamics format as above to initialise simulations. Refer to AtomsIO for more information.