# Atoms

## Constructors and types

`Electrum.NamedAtom`

— Type`NamedAtom`

Stores information about an atom, which includes a name which may be up to 15 codepoints long, and the atomic number.

`Electrum.AbstractAtomPosition`

— Type`AbstractAtomPosition{D}`

Supertype that describes atomic positions in `D`

dimensions, which include name, coordinate, and occupancy information.

`Electrum.CartesianAtomPosition`

— Type`CartesianAtomPosition{D}`

Describes an absolute atomic position. The coordinate in the `pos`

field is assumed to be given in bohr.

Occupancy information is provided in the `occ`

field. Note that no checking is done to ensure that the occupancy is a reasonable value.

`Electrum.FractionalAtomPosition`

— Type`FractionalAtomPosition{D}`

Describes an atomic position within a crystal or other periodic structure. The coordinate in the `pos`

field is assumed to be given relative to the basis vectors of the structure.

Occupancy information is provided in the `occ`

field. Note that no checking is done to ensure that the occupancy is a reasonable value.

`Electrum.AbstractAtomList`

— Type`AbstractAtomList{D}`

Supertype for lists of atomic positions in `D`

dimensions.

`Electrum.AtomList`

— Type`AtomList{D}`

Contains a list of `CartesianAtomPosition`

objects, corresponding to atoms in free space without boundary conditions.

`Electrum.PeriodicAtomList`

— Type`PeriodicAtomList{D}`

Contains a list of `FractionalAtomPosition`

objects with an associated basis, corresponding to atoms in a system with periodicity.

## Extracting data

`Electrum.name`

— Function`name(a::NamedAtom) -> String`

Returns the name associated with a `NamedAtom`

. For atoms constructed with only an atomic number, the name will be the atomic symbol. This function returns a `Base.String`

for compatibility, not the `InlineStrings.InlineString15`

from the backing field.

**Examples**

```
julia> a = NamedAtom("Cl1", 17)
NamedAtom("Cl1", 17)
julia> name(a)
"Cl1"
```

`Electrum.atomic_number`

— Function`atomic_number(a::NamedAtom)`

Returns the atomic number associated with a `NamedAtom`

. For atoms constructed with only a name, the atomic number returned will be that associated with the symbol if the symbol exactly corresponds to an atom name.

**Examples**

```
julia> a = NamedAtom("Cl1", 17)
NamedAtom("Cl1", 17)
julia> atomic_number(a)
17
```

`Electrum.isdummy`

— Function`isdummy(a::NamedAtom) -> Bool`

Returns `true`

if the atomic number of a `NamedAtom`

is zero, `false`

otherwise. Atoms with zero as the atomic number are treated as dummy atoms, which may be used to reference specific positions in a molecule or crystal.

**Examples**

```
julia> a = NamedAtom("Cl1", 17)
NamedAtom("Cl1", 17)
julia> b = NamedAtom("test")
NamedAtom("test", 0)
julia> isdummy(a)
false
julia> isdummy(b)
true
```

`Electrum.atomtypes`

— Function`atomtypes(l::AbstractAtomList; dummy=false) -> Vector{NamedAtom}`

Returns all unique `NamedAtom`

types found in an `AbstractAtomList`

. This vector is sorted by atomic number.

The `dummy`

keyword controls whether dummy atoms are counted as a separate atom type (`false`

by default).

To obtain a list of all unique atom names or atomic numbers, use `name.(atomtypes(l))`

or `num.(atomtypes(l))`

.

`Electrum.natomtypes`

— Function`natomtypes(l::AbstractAtomList; dummy=false) -> Int`

Returns the number of types of atoms in an `AbstractAtomList`

.

The `dummy`

keyword controls whether dummy atoms are counted as a separate atom type (`false`

by default).

The `use_names`

keyword determines whether the atoms counted separately based on atom names. By default, this is equal to `dummy`

, so names are only factored in if dummy atoms are counted.

`Electrum.atomcounts`

— Function`atomcounts(l::AbstractAtomList; dummy=false, names=false) -> Vector{Pair{NamedAtom,Int}}`

Returns pairs of atoms and the number of atoms in the `AtomList`

with that atomic number.

The `dummy`

keyword controls whether dummy atoms are counted as a separate atom type (`false`

by default).

The `use_names`

keyword determines whether the atoms counted separately based on atom names. By default, this is equal to `dummy`

, so names are only factored in if dummy atoms are counted.

`Base.isapprox`

— Method`isapprox(a::AbstractAtomPosition, b::AbstractAtomPosition; atol = sqrt(eps(Float64)))...)`

Checks whether two atomic sites are approximately equal to one another. The function returns `true`

if the atomic numbers of the atoms are the same, and the coordinates of the atoms differ by no more than `atol`

.

`Electrum.distance`

— Method```
distance(a1::CartesianAtomPosition, a2::CartesianAtomPosition) -> Float64
distance(b::LatticeBasis, a1::FractionalAtomPosition, a2::FractionalAtomPosition) -> Float64
```

Calculates the distance between two `FractionalAtomPosition`

objects in the same basis `b`

.

## Moving and processing atom lists

`Electrum.deduplicate`

— Function```
deduplicate(l::AbstractVector{T<:AbstractAtomPosition}; atol=sqrt(eps(Float64))) -> Vector{T}
deduplicate(l::AbstractAtomList; atol=sqrt(eps(Float64))) -> <:AbstractAtomList
```

Removes atoms that are duplicates or close to being duplicates. In order to be considered duplicates, the atoms must have both the atomic number, and their coordinates must be approximately equal (to within a total distance of `sqrt(eps(Float64))`

).

`Electrum.move_into_cell`

— Function```
move_into_cell(l::AbstractVector{T<:FractionalAtomPosition}; atol=sqrt(eps(Float64)))
-> Vector{T}
move_into_cell(l::PeriodicAtomList; atol=sqrt(eps(Float64))) -> PeriodicAtomList
```

Moves atoms that may exist outside of the bounds of a unit cell (meaning that their fractional coordinates are not between 0 and 1) into the unit cell.

`Electrum.supercell`

— Function`supercell(l::PeriodicAtomList, M) -> PeriodicAtomList`

Creates a new `AtomList`

with the basis vectors of a supercell generated by transforming the basis vectors of the space by `M`

, which may be an integer matrix, an integer vector which is treated as a diagonal matrix, or a plain integer, which performs a uniform scaling. This function will also generate new atomic positions to fill the cell.

The function performs this transformation by calculating the Smith normal form of the transformation matrix. This matrix provides the integer scaling factors needed to stretch the supercell, and the left unimodular factor is then used to perform the final transformation.