System#
Directory: libfly/system
The system
folder contains a collection of data structures for representing atoms, groups of atoms and the space the atoms exist in. Everything is contained within the namespace fly::system
.
Simulation space#
File: libfly/system/box.hpp
Classes for describing the simulation space.
Atoms in libFLY exist within a simulation space (or box) and this space is often periodic. Periodic boxes must tessellate in N-dimensional space hence, libFLY’s boxes are parallelotopes. The parallelotopes is described by a series of basis vectors. These are assembled into an upper-triangular matrix of the form:
with: each column corresponding to a basis vector, all non-zero entries positive and all diagonal elements non-zero. This constrains some of the rotational degrees of freedom of the parallelotope and ensures the existence of an inverse.
The canonical cell/box/simulation-space is the volume of space inside the parallelotope with edges formed from the basis vectors rooted at the origin. Along periodic axes atoms are allowed to have projected coordinates outside the canonical-cell however, along non-periodic axes atoms must be inside the canonical cell.
LibFLY resolved periodicity using ghost atoms, these are the periodic images of real atom. To do this efficiently the canonical box is split into a grid of smaller parallelotopes. These grid cells are determined by the maximum interatomic interaction distance.
Generalised box#
-
class Box#
Generalised simulation box.
Essentially a
std::variant
of all supported crystal-systems /boxes.Public Types
-
using Grid = std::variant<OrthoGrid, TriGrid>#
The result of calling Box::make_grid()
Public Functions
-
inline Box(Mat const &basis, Arr<bool> const &periodic)#
Construct a new Box box object.
Automatically select the optimal underlying crystal system.
- Parameters:
basis – Matrix with columns equal to the basis vectors of the box (parallelotope).
periodic – True for each periodic axis.
-
inline Mat basis() const#
Fetch the basis vectors of this cell.
- Returns:
Mat A matrix with each column corresponding to a basis vector.
-
template<typename E>
inline Vec canon_image(Eigen::MatrixBase<E> const &x) const# Maps an atom into the canonical cell.
Warning
Assumes atoms are within the extents of the non-periodic axes!
-
inline auto get() const noexcept -> std::variant<Orthorhombic, Triclinic> const&#
Get the variant underlying this box.
-
template<typename T>
inline bool holding() const noexcept# Check if Box is currently using
T
as its crystal system.
-
inline std::variant<OrthoGrid, TriGrid> make_grid(double r_cut) const#
Make an
std::variant
of grid objects.Grids have a common API, unwrap with
std::visit
.- Parameters:
r_cut – The cut-off radius for atomic interactions.
-
inline bool periodic(Eigen::Index i) const#
Query if the
i
th axis is periodic.
-
inline auto slow_min_image_computer() const#
Get a lambda that can compute the minimum image distance.
Specifically this function returns a lambda,
l
, such thatl(a, b)
(witha
andb
the position vectors of two atom) returns the norm of the minimum image vector connectinga
andb
.
-
using Grid = std::variant<OrthoGrid, TriGrid>#
Specialised boxes#
In theory libFLY could detect the most efficient crystal-system for any basis-set and produce optimal code. Unfortunately, this is a lot of work hence, libFLY uses a smaller set - suitable for the majority of cases. If you would like to read more about these specialised boxes see:
Properties#
File: libfly/system/property.hpp
The basic building block for atoms in libFLY.
Properties in libFLY describe an atomic quantity i.e. mass, position, etc. They take the form of fixed-size matrices and must always be derived from the Property class. The most fundamental property that every atom must have is a fly::TypeID. Properties can either be associated per-atom using the fly::system::Atom, fly::system::VoS and fly::system::SoA data-structures or per-type using the fly::system::TypeMap.
-
template<typename Scalar, int Rows = 1, int Cols = 1, template<typename, auto...> typename Rep = Eigen::Matrix>
struct Property# A base type to derive from for defining properties.
Properties may be fixed-size matrices/arrays of arithmetic types or scalar (1x1) default-constructible types.
1x1 matrices are unwrapped into scalars.
A selection of canonical properties , deriving from this type, are provided in the inline namespace
builtin_properties
.- Template Parameters:
Scalar – This property represents a matrix of Scalar elements.
Rows – Number of rows in this property
Cols – Number of colums in this property
Rep – The Eigen3 template, Eigen::[matrix||array], to use for this property.
Public Types
-
using array_t = Eigen::Array<Scalar, Eigen::Dynamic, 1>#
The Eigen type used to store a dynamic collection of contiguous matrix_t.
-
using matrix_cref_t = std::conditional_t<is_1x1, Scalar const&, Eigen::Map<matrix_t const>>#
A const-reference-like type to a matrix_t.
-
using matrix_ref_t = std::conditional_t<is_1x1, Scalar&, Eigen::Map<matrix_t>>#
A reference-like type to a matrix_t.
Public Static Functions
-
static inline constexpr int size()#
Get the number of elements in the matrix_t.
Built-in#
-
namespace builtin_properties#
An inline namespace providing a selection of canonical properties for Atom.
Variables
-
constexpr Acceleration a_#
Acceleration literal.
-
constexpr PotentialGradient g_#
PotentialGradient literal.
-
constexpr MomentInertia I_#
MomentInertia literal.
-
struct Acceleration : public fly::system::Property<double, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for atom’s acceleration.
-
struct Axis : public fly::system::Property<double, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for atom’s contribution to a dimer axis.
-
struct Charge : public fly::system::Property<double>#
- #include <libfly/system/property.hpp>
Tag type for atom’s charge.
-
struct Colour : public fly::system::Property<int>#
- #include <libfly/system/property.hpp>
Tag type for an atom’s colour.
Colour is an abstract property, atoms with the same colour are interchangeable in geometry contexts. For example, a frozen and non frozen Fe atom must have different colours.
-
struct Delta : public fly::system::Property<double, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for a changes in some atomic property.
-
struct Diameter : public fly::system::Property<double>#
- #include <libfly/system/property.hpp>
Tag type for atom’s effective diameter.
-
struct Frozen : public fly::system::Property<bool>#
- #include <libfly/system/property.hpp>
Tag type for atom’s status as a frozen atom.
Note this cannot be written to a GSD file as it a boolean.
-
struct Hash : public fly::system::Property<int>#
- #include <libfly/system/property.hpp>
Tag type for a particle local environment hash.
-
struct Image : public fly::system::Property<std::int32_t, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for atom’s image count, i.e. how many times atom has wrapped.
Not used by libFLY, for consistency with HOOMD schema.
-
struct Index : public fly::system::Property<Eigen::Index>#
- #include <libfly/system/property.hpp>
Tag type for atom’s index i.e. position in some array.
-
struct Mass : public fly::system::Property<double>#
- #include <libfly/system/property.hpp>
Tag type for atom’s mass.
-
struct MomentInertia : public fly::system::Property<double>#
- #include <libfly/system/property.hpp>
Tag type for atom’s moment of inertia in an atoms body frame.
-
struct Position : public fly::system::Property<double, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for atom’s position in real space.
-
struct PotentialGradient : public fly::system::Property<double, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for atom’s potential gradient acting on an atom.
-
struct Type : public fly::system::Property<char, 32, 1, Eigen::Array>#
- #include <libfly/system/property.hpp>
Tag type for atom’s type.
Types are abstract labels assigned to atoms, if two atoms have the same type they are completely interchangeable in every way.
-
struct TypeID : public fly::system::Property<std::uint32_t>#
- #include <libfly/system/property.hpp>
Tag type for atom’s id.
Each atom has a Type, an atoms TypeID is a number between 0 and N - 1 with N the number of types in the simulation. A TypeMap object performs the transformation from TypeId -> Type.
-
struct Velocity : public fly::system::Property<double, spatial_dims>#
- #include <libfly/system/property.hpp>
Tag type for atom’s velocity in real space.
-
constexpr Acceleration a_#
Property generic data-structures#
Atom class#
File: libfly/system/atom.hpp
The basic building block for atoms in libFLY.
-
template<typename ...T>
struct Atom : public fly::system::detail::AtomMem<T># The libfly representation of an atom.
Libfly uses this type to build atoms to allow integration with libFLY’s containers. An Atom behaves as a structure of its properties , which are accessed through
operator[]
.Example:
#include "libfly/system/atom.hpp" #include "libfly/system/property.hpp" void example_atom() { // Define a property to represent spin that is a scalar of type bool. struct spin : fly::system::Property<bool> {}; // Define a property to represent position that is a vector of 3 doubles. // Note there is a built-in property for this (Position). struct xyz : fly::system::Property<double, 3> {}; // Define a property to represent the inertia tensor that is a 3x3 matrix of doubles. struct I : fly::system::Property<double, 3, 3> {}; // Create an atom fly::system::Atom<spin, xyz, I> atom{ true, {1, 2, 3}, I::matrix_t::Zero(), // I::matrix_t is Eigen::Matrix<double, 3, 3> }; // Access and set the spin property atom[spin{}] = false; }
- Template Parameters:
T – a series of empty types, derived from
Property
, to describe each member.
Type map#
File: libfly/system/typemap.hpp
-
template<typename ...T>
class TypeMap : private fly::system::SoA<Type, T...># Utility for mapping an atom’s TypeID to a Type and its properties.
This is used for properties that are the same for many atoms e.g. atomic numbers, by default each TypeID must always have a Type property.
Note
TypeMap has special handling for getting and setting
Type
’sType::matrix_t
to string-like types for QoL.- Template Parameters:
T – Tags derived from
Property
, to describe each property.
Public Functions
-
inline explicit TypeMap(Eigen::Index num_types)#
Construct a TypeMap to hold
num_types
types.Warning
All the new properties are uninitialised.
-
template<typename ...U, typename = std::enable_if_t<!detail::same_properties<TypeMap, U...>::value && std::is_constructible_v<SOA, SoA<Type, U...> const&>>>
inline explicit TypeMap(TypeMap<U...> const &map)# Construct a new TypeMap by slicing a different kind of TypeMap.
-
template<typename U>
inline auto get(std::uint32_t id, [[maybe_unused]] U tag) const -> decltype(auto)# Get a property form the map.
- Parameters:
id – The TypeID of the type who’s property you are getting.
tag – Tag to disambiguate property you would like.
-
inline auto get(std::uint32_t id, Type, bool truncate = true) const -> std::string_view#
Overload of get() for
Type
that returns a string_view of the type name.Tip
With
truncate = true
this overload has some runtime-cost to count the char’s in the array.If you would like to call the template overload to get a mapped Eigen::Array use explicit template syntax:
TypeMap map(1); // set the Type // map.get<Type>(0, tp_)
- Parameters:
truncate – If
true
truncate the returned string_view to the non-null portion.id – The typeID of the type who’s property you are getting.
-
inline auto set(std::uint32_t id, [[maybe_unused]] Type tag, std::string_view value) -> void#
Overload of set() for Type that accepts string_views.
- Parameters:
id – The TypeID of the type who’s property you are getting.
tag – Tag to disambiguate property you would like.
value – Value to write into the map.
-
template<typename U, typename V = typename U::matrix_t>
inline auto set(std::uint32_t id, [[maybe_unused]] U tag, V &&value) -> std::enable_if_t<std::is_assignable_v<typename U::matrix_t&, V&&>># Set a property in the map.
- Parameters:
id – The TypeID of the type who’s property you are getting.
tag – Tag to disambiguate property you would like.
value – Value to write into the map.
Friends
- friend class ::fly::io::BinaryFile
Structure of arrays#
File: libfly/system/SoA.hpp
-
template<typename ...Pr>
class SoA : public fly::system::detail::Adaptor<Pr># A container for atoms that stores each property in its own array.
The default container type used in the libfly; an
SoA
models an array ofAtom
types but decomposes the atom type and stores each property in a separate array. This enables efficient cache use. LikeAtom
, the properties of the “atom” are described through a series of template parameters which should inherit fromProperty
. The properties of each atom can be accessed by the index of the atom or as anEigen::Array
to enable collective operations.SoA also supports slicing and reference properties which transform that property into a view, this enables SoA to act as a concrete type in interfaces whilst allowing implicit conversions from any compatible SoA.
Example:
#include "libfly/system/SoA.hpp" #include "libfly/system/property.hpp" // Define a property to represent spin that is a scalar of type bool. struct spin : fly::system::Property<bool> {}; // Define a property to represent position that is a vector of 3 doubles. // Note there is a built-in property for this (Position). struct xyz : fly::system::Property<double, 3> {}; // Define a property to represent the inertia tensor that is a 3x3 matrix of doubles. struct I : fly::system::Property<double, 3, 3> {}; // Use reference property -> pass by value. void zero_xyz(fly::system::SoA<xyz &> view_xyz) { // Zero the positions view_xyz[xyz{}] = 0; } void example_SoA() { // SoA of 10 uninitialized atoms. fly::system::SoA<spin, xyz, I> atoms(10); // Set the spin of the fist atom. atoms(spin{}, 0) = true; // Implicitly sliced at call. zero_xyz(atoms); }
- Template Parameters:
Pr – a series of empty types, derived from
Property
, to describe each member.
Public Functions
-
inline explicit SoA(Eigen::Index size)#
Construct a new SoA containing ‘size’ atoms.
Warning
New atoms are uninitialized, non-owning SoA’s contain
nullptr
.
-
template<typename ...T, typename = std::enable_if_t<owns_none && constructible<SoA<T...>&&>>>
inline SoA(SoA<T...> &&other)# Implicitly construct a new SoA object from SoA ‘other’ with different properties .
Only SFINE enabled if this SoA owns non of its arrays and this SoA is actually constructable from other.
-
template<typename ...T, typename = std::enable_if_t<!owns_none && constructible<SoA<T...>&&>>, typename = void>
inline explicit SoA(SoA<T...> &&other)# Explicitly construct a new SoA object from SoA ‘other’ with different properties .
SFINE enabled if this SoA owns some of its arrays and this SoA is actually constructable from other.
-
template<typename ...T, typename = std::enable_if_t<owns_none && constructible<SoA<T...>&>>>
inline SoA(SoA<T...> &other)# Implicitly construct a new SoA object from SoA ‘other’ with different properties .
Only SFINE enabled if this SoA owns non of its arrays and this SoA is actually constructable from other.
-
template<typename ...T, typename = std::enable_if_t<!owns_none && constructible<SoA<T...>&>>, typename = void>
inline explicit SoA(SoA<T...> &other)# Explicitly construct a new SoA object from SoA ‘other’ with different properties .
SFINE enabled if this SoA owns some of its arrays and this SoA is actually constructable from other.
-
template<typename ...T, typename = std::enable_if_t<owns_none && constructible<SoA<T...> const&>>>
inline SoA(SoA<T...> const &other)# Implicitly construct a new SoA object from SoA ‘other’ with different properties .
Only SFINE enabled if this SoA owns non of its arrays and this SoA is actually constructable from other.
-
template<typename ...T, typename = std::enable_if_t<!owns_none && constructible<SoA<T...> const&>>, typename = void>
inline explicit SoA(SoA<T...> const &other)# Explicitly construct a new SoA object from SoA ‘other’ with different properties .
SFINE enabled if this SoA owns some of its arrays and this SoA is actually constructable from other.
-
template<bool OwnsAll = owns_all>
inline auto destructive_resize(Eigen::Index new_size) -> std::enable_if_t<OwnsAll, bool># Resize the SoA, no-op if
size() == new_size
.Warning
Destroys all the data in the SoA, new atoms are all uninitialized.
- Returns:
true
if resize occurred,false
otherwise.
-
SoA &operator=(SoA&&) = default#
Defaulted move assignment operator.
See the note on assignment to references.
-
SoA &operator=(SoA const&) = default#
Defaulted copy assignment operator.
See the note on assignment to references.
-
template<typename T, typename = std::enable_if_t<different_SoA_v<T>>>
inline SoA &operator=(T &&other)# Assign to a SoA with with different properties .
Note
Assignment to reference properties follows pointer-semantics:
#include "libfly/system/SoA.hpp" #include "libfly/system/property.hpp" void SoA_assign() { // Define a property to represent position that is a vector of 3 doubles. // Note there is a built-in property for this (Position). struct xyz : fly::system::Property<double, 3> {}; fly::system::SoA<xyz> a(10); fly::system::SoA<xyz> b(10); a[xyz{}] = 1; b[xyz{}] = 2; fly::system::SoA<xyz &> view_a = a; fly::system::SoA<xyz &> view_b = b; fly::system::SoA<xyz &> view_b2 = b; view_a = view_b; // This does NOT set a[xyz{}] to b[xyz{}] view_a = std::move(view_b); // Neither does this view_a[xyz{}] = view_b2[xyz{}]; // This does :) }
-
template<typename T, typename U>
inline auto rebind(T, U &other) -> std::enable_if_t<(std::is_same_v<T&, Pr> || ...) || (std::is_same_v<T const&, Pr> || ...)># Rebind a reference property to point at ‘’other’’.
- Parameters:
other – Property tag
- Returns:
void
Public Static Attributes
-
template<typename T>
static constexpr bool different_SoA_v = detail::different_SoA<SoA<Pr...>, remove_cref_t<T>>::value# Detect if a type is a specialization of a SoA but different from this specialization.
Aliases#
Array of structures#
File: libfly/system/VoS.hpp
-
template<typename ...T>
class VoS : public fly::Vector<Atom<T...>># A container that models a std::vector of atoms.
The properties of the “atom” are described through a series of template parameters which should inherit from
Property
Example:
#include "libfly/system/VoS.hpp" #include "libfly/system/atom.hpp" #include "libfly/system/property.hpp" void example_VoS() { // Define a property to represent position that is a vector of 3 doubles. // Note there is a built-in property for this (Position). struct xyz : fly::system::Property<double, 3> {}; fly::system::VoS<xyz> atoms; // Empty VoS atoms.emplace_back({1, 2, 3}); // Add an atom at position {1, 2, 3} fly::system::Atom<xyz>& first_atom = atoms[0]; // Reference to first atom. atoms.push_back(first_atom); // Make a second atom a copy of the first. }
Todo
Work out how to make inherited functions display with
using
.- Template Parameters:
T – a series of empty types, derived from
Property
, to describe each member.
Supercells#
File: libfly/system/supercell.hpp
-
template<typename Map, typename ...T>
class Supercell : public fly::system::SoA<TypeID, T...># LibFLY’s representation of a system of atoms.
The Supercell is libFLY’s amalgamation of all the data required for a simulation. It is a SoA containing all the atoms in the system has a
Box
and aTypeMap
. A Supercell always has theTypeID
property for each atom and accepts the rest as template arguments.- Template Parameters:
Map – A specialisation of fly::system::TypeMap.
-
template<typename ...T, typename ...U>
auto fly::system::make_supercell(Box const &box, TypeMap<U...> const &map, Eigen::Index num_atoms) -> Supercell<TypeMap<U...>, T...># Utility to construct a new Supercell to store
num_atoms
atoms.Uses partial function-template argument deduction to deduce Supercell’s template parameters.
- Template Parameters:
Property – tags derived from
Property
.- Parameters:
- Returns:
A constructed supercell with the Map template-parameter deduced.
Hessians#
File: libfly/system/hessian.hpp
Represent and manipulate Hessians.
-
class Hessian#
A class to represent the blocked hessian of a system.
The hessian is a symmetric nm by nm matrix with m the number of active atoms and n the number of spatial dimensions. Each n by n sub-matrix is a “block” of the hessian.
Public Types
-
using Matrix = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>#
The Matrix types used to store the eigen vectors of the hessian.
-
using Vector = Eigen::Vector<double, Eigen::Dynamic>#
The vector types used to store the eigen values of the hessian.
Public Functions
-
inline eigen_t eigen()#
Computes the eigenvalues and eigenvectors.
See: https://eigen.tuxfamily.org/dox/classEigen_1_1SelfAdjointEigenSolver.html only reads the lower diagonal portion of the matrix.
-
inline Vector const &eigenvalues()#
Compute and return a reference to an ordered vector of Eigen Values.
See: https://eigen.tuxfamily.org/dox/classEigen_1_1SelfAdjointEigenSolver.html only reads the lower diagonal portion of the matrix.
The eigenvalues are repeated according to their algebraic multiplicity, so there are as many eigenvalues as rows in the matrix. The eigenvalues are sorted in increasing order.
-
inline auto mass_weight(TypeMap<Mass> const &map, system::viewSoA<TypeID> const &in) -> void#
Transform to a mass-weighted hessian.
- Parameters:
map – The type map containing the masses of the atoms as a function of their type ID.
in – The view containing the atom IDs.
-
inline auto operator()(Eigen::Index i, Eigen::Index j)#
Get a view of the block corresponding to the
ij
atom pair.- Parameters:
i – The index (in the hessian matrix) of the first atom in the pair.
j – The index (in the hessian matrix) of the second atom in the pair.
-
struct eigen_t#
A struct that contains references to the eigen values/vectors.
-
using Matrix = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>#