CHFL_FRAME
¶
CHFL_FRAME
¶An opaque type handling frames.
A CHFL_FRAME
contains data from one simulation step: the current unit cell, the topology, the positions, and the velocities of the particles in the system. If some information is missing (topology or velocity or unit cell), the corresponding data is filled with a default value.
chfl_frame
(void)¶Create a new empty frame.
The caller of this function should free the allocated memory using chfl_frame_free
.
CHFL_FRAME* frame = chfl_frame();
if (frame == NULL) {
/* handle error */
}
chfl_frame_free(frame);
chfl_last_error
to learn about the error.
chfl_frame_copy
(const CHFL_FRAME *frame)¶Get a copy of a frame
.
The caller of this function should free the associated memory using chfl_frame_free
.
CHFL_FRAME* frame = chfl_frame();
CHFL_FRAME* copy = chfl_frame_copy(frame);
if (copy == NULL) {
/* handle error */
}
chfl_frame_free(copy);
chfl_frame_free(frame);
chfl_last_error
to learn about the error.
chfl_frame_atoms_count
(const CHFL_FRAME *frame, uint64_t *size)¶Get the current number of atoms in a frame
in the integer pointed to by size
CHFL_FRAME* frame = chfl_frame();
chfl_frame_resize(frame, 42);
uint64_t atoms = 0;
chfl_frame_atoms_count(frame, &atoms);
assert(atoms == 42);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_resize
(CHFL_FRAME *frame, uint64_t size)¶Resize the positions, velocities and topology in the frame
, to have space for size
atoms.
This function may invalidate any pointer to the positions or the velocities if the new size is bigger than the old one. In all the cases, previous data is conserved. This function conserve the presence or absence of velocities.
CHFL_FRAME* frame = chfl_frame();
chfl_frame_resize(frame, 55);
uint64_t atoms = 0;
chfl_frame_atoms_count(frame, &atoms);
assert(atoms == 55);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_add_atom
(CHFL_FRAME *frame, const CHFL_ATOM *atom, const chfl_vector3d position, const chfl_vector3d velocity)¶Add an atom
and the corresponding position
and velocity
data to a frame
.
velocity
can be NULL
if no velocity is associated with the atom.
CHFL_FRAME* frame = chfl_frame();
CHFL_ATOM* atom = chfl_atom("C");
chfl_frame_add_atom(frame, atom, (chfl_vector3d){1, 2, 3}, NULL);
chfl_atom_free(atom);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_remove
(CHFL_FRAME *frame, uint64_t i)¶Remove the atom at index i
in the frame
.
This modify all the atoms indexes after i
, and invalidate any pointer obtained using chfl_frame_positions
or chfl_frame_velocities
.
CHFL_FRAME* frame = chfl_frame();
chfl_frame_resize(frame, 42);
uint64_t atoms = 0;
chfl_frame_atoms_count(frame, &atoms);
assert(atoms == 42);
chfl_frame_remove(frame, 37);
chfl_frame_remove(frame, 30);
chfl_frame_remove(frame, 15);
chfl_frame_atoms_count(frame, &atoms);
assert(atoms == 39);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_positions
(CHFL_FRAME *frame, chfl_vector3d **positions, uint64_t *size)¶Get a pointer to the positions array from a frame
.
Positions are stored as a size x 3
array, this function set the pointer pointed to by positions
to point to the first element of this array, and give the number of atoms in the integer pointed to by size
.
If the frame is resized (by writing to it, or calling chfl_frame_resize
, chfl_frame_remove
or chfl_frame_add_atom
), the pointer is invalidated. If the frame is freed using chfl_frame_free
, the pointer is freed too. There is then no need to free the *positions
pointer for the caller of this function.
CHFL_FRAME* frame = chfl_frame();
chfl_vector3d* positions = NULL;
uint64_t natoms = 0;
chfl_frame_positions(frame, &positions, &natoms);
for (uint64_t i=0; i<natoms; i++) {
// use positions[i] here
}
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_velocities
(CHFL_FRAME *frame, chfl_vector3d **velocities, uint64_t *size)¶Get a pointer to the velocities array from a frame
.
Velocities are stored as a size x 3
array, this function set the pointer pointed to by positions
to point to the first element of this array, and give the number of atoms in the integer pointed to by size
.
If the frame is resized (by writing to it, or calling chfl_frame_resize
, chfl_frame_remove
or chfl_frame_add_atom
), the pointer is invalidated. If the frame is freed using chfl_frame_free
, the pointer is freed too. There is then no need to free the *velocity
pointer for the caller of this function.
If the frame does not have velocity, this will return an error. Use chfl_frame_add_velocities
to add velocities to a frame before calling this function.
CHFL_FRAME* frame = chfl_frame();
chfl_frame_add_velocities(frame);
chfl_vector3d* velocities = NULL;
uint64_t natoms = 0;
chfl_frame_positions(frame, &velocities, &natoms);
for (uint64_t i=0; i<natoms; i++) {
// use velocities[i] here
}
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_has_velocities
(const CHFL_FRAME *frame, bool *has_velocities)¶Check if this frame
contains velocity data, and store the result in has_velocities
CHFL_FRAME* frame = chfl_frame();
bool velocities = true;
chfl_frame_has_velocities(frame, &velocities);
assert(velocities == false);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_add_velocities
(CHFL_FRAME *frame)¶Add velocity data to this frame
.
The velocities are initialized to (chfl_vector3d){0, 0, 0}
. If the frame already has velocities, this does nothing.
CHFL_FRAME* frame = chfl_frame();
chfl_frame_add_velocities(frame);
bool velocities = false;
chfl_frame_has_velocities(frame, &velocities);
assert(velocities == true);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_set_cell
(CHFL_FRAME *frame, const CHFL_CELL *cell)¶Set the unit cell of a frame
to cell
.
CHFL_FRAME* frame = chfl_frame();
CHFL_CELL* cell = chfl_cell((chfl_vector3d){10, 10, 12});
chfl_frame_set_cell(frame, cell);
chfl_cell_free(cell);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_set_topology
(CHFL_FRAME *frame, const CHFL_TOPOLOGY *topology)¶Set the topology of a frame
to topology
.
Calling this function with a topology that does not contain the right number of atom will return an error.
CHFL_FRAME* frame = chfl_frame();
CHFL_TOPOLOGY* topology = chfl_topology();
{
// Build the topology
CHFL_ATOM* O = chfl_atom("O");
CHFL_ATOM* H = chfl_atom("H");
chfl_topology_add_atom(topology, O);
chfl_topology_add_atom(topology, H);
chfl_topology_add_atom(topology, H);
chfl_atom_free(O);
chfl_atom_free(H);
}
chfl_frame_set_topology(frame, topology);
chfl_topology_free(topology);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_add_bond
(CHFL_FRAME *frame, uint64_t i, uint64_t j)¶Add a bond between the atoms at indexes i
and j
in the frame
.
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_remove_bond
(CHFL_FRAME *frame, uint64_t i, uint64_t j)¶Remove any existing bond between the atoms at indexes i
and j
in the frame
.
This function does nothing if there is no bond between i
and j
.
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_add_residue
(CHFL_FRAME *frame, const CHFL_RESIDUE *residue)¶Add a copy of residue
to this frame
.
The residue id must not already be in this frame’s topology, and the residue must contain only atoms that are not already in another residue.
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_step
(const CHFL_FRAME *frame, uint64_t *step)¶Get a frame
step, i.e. the frame number in the trajectory in the integer pointed to by step
.
CHFL_FRAME* frame = chfl_frame();
uint64_t step = 3;
chfl_frame_step(frame, &step);
assert(step == 0);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_set_step
(CHFL_FRAME *frame, uint64_t step)¶Set a frame
step, i.e. the frame number in the trajectory to step
.
CHFL_FRAME* frame = chfl_frame();
chfl_frame_set_step(frame, 678);
uint64_t step = 0;
chfl_frame_step(frame, &step);
assert(step == 678);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_guess_topology
(CHFL_FRAME *frame)¶Guess the bonds, angles and dihedrals in a frame
.
The bonds are guessed using a distance-based algorithm, and then angles and dihedrals are guessed from the bonds.
// Building a frame containing a Cl2 molecule
CHFL_FRAME* frame = chfl_frame();
CHFL_ATOM* Cl = chfl_atom("Cl");
chfl_frame_add_atom(frame, Cl, (chfl_vector3d){0, 0, 0}, NULL);
chfl_frame_add_atom(frame, Cl, (chfl_vector3d){2, 0, 0}, NULL);
chfl_atom_free(Cl);
// Check that the topology does not contain any bond
CHFL_TOPOLOGY* topology = chfl_topology_from_frame(frame);
uint64_t bonds = 0;
chfl_topology_bonds_count(topology, &bonds);
assert(bonds == 0);
chfl_topology_free(topology);
chfl_frame_guess_topology(frame);
// Get a copie of the new topology
topology = chfl_topology_from_frame(frame);
chfl_topology_bonds_count(topology, &bonds);
assert(bonds == 1);
chfl_topology_free(topology);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_distance
(const CHFL_FRAME *frame, uint64_t i, uint64_t j, double *distance)¶Get the distance between the atoms at indexes i
and j
in the frame
, accounting for periodic boundary conditions. The result is placed in distance
, and expressed in angstroms.
CHFL_FRAME* frame = chfl_frame();
CHFL_ATOM* atom = chfl_atom("");
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){1, 2, 3}, NULL);
double distance = 0;
chfl_frame_distance(frame, 0, 1, &distance);
assert(distance == sqrt(14));
chfl_atom_free(atom);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_angle
(const CHFL_FRAME *frame, uint64_t i, uint64_t j, uint64_t k, double *angle)¶Get the angle formed by the atoms at indexes i
, j
and k
in the frame
, accounting for periodic boundary conditions. The result is placed in angle
, and expressed in radians.
CHFL_FRAME* frame = chfl_frame();
CHFL_ATOM* atom = chfl_atom("");
chfl_frame_add_atom(frame, atom, (chfl_vector3d){1, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 1, 0}, NULL);
double angle = 0;
chfl_frame_angle(frame, 0, 1, 2, &angle);
assert(fabs(angle - M_PI / 2) < 1e-12);
chfl_atom_free(atom);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_dihedral
(const CHFL_FRAME *frame, uint64_t i, uint64_t j, uint64_t k, uint64_t m, double *dihedral)¶Get the angle formed by the atoms at indexes i
, j
, k
and m
in the frame
, accounting for periodic boundary conditions. The result is placed in dihedral
, and expressed in radians.
CHFL_FRAME* frame = chfl_frame();
CHFL_ATOM* atom = chfl_atom("");
chfl_frame_add_atom(frame, atom, (chfl_vector3d){1, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 1, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 1, 1}, NULL);
double dihedral = 0;
chfl_frame_dihedral(frame, 0, 1, 2, 3, &dihedral);
assert(fabs(dihedral - M_PI / 2) < 1e-12);
chfl_atom_free(atom);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_out_of_plane
(const CHFL_FRAME *frame, uint64_t i, uint64_t j, uint64_t k, uint64_t m, double *distance)¶Get the out of plane distance formed by the atoms at indexes i
, j
, k
and m
in the frame
, accounting for periodic boundary conditions. The result is placed in distance
and expressed in angstroms.
This is the distance betweent the atom j and the ikm plane. The j atom is the center of the improper dihedral angle formed by i, j, k and m.
CHFL_FRAME* frame = chfl_frame();
CHFL_ATOM* atom = chfl_atom("");
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 0, 2}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){1, 0, 0}, NULL);
chfl_frame_add_atom(frame, atom, (chfl_vector3d){0, 1, 0}, NULL);
double distance = 0;
chfl_frame_out_of_plane(frame, 0, 1, 2, 3, &distance);
assert(fabs(distance - 2) < 1e-12);
chfl_atom_free(atom);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_set_property
(CHFL_FRAME *frame, const char *name, const CHFL_PROPERTY *property)¶Add a new property
with the given name
to this frame
.
If a property with the same name already exists, this function override the existing property with the new one.
CHFL_FRAME* frame = chfl_frame();
CHFL_PROPERTY* property = chfl_property_double(-23);
chfl_frame_set_property(frame, "this", property);
chfl_property_free(property);
property = chfl_frame_get_property(frame, "this");
double value = 0;
chfl_property_get_double(property, &value);
assert(value == -23);
chfl_property_free(property);
chfl_frame_free(frame);
chfl_last_error
to learn about the error if the status code is not CHFL_SUCCESS
.
chfl_frame_get_property
(const CHFL_FRAME *frame, const char *name)¶Get a property with the given name
in this frame
.
This function returns NULL
is no property exist with the given name.
The user of this function is responsible to deallocate memory using the chfl_property_free
function.
CHFL_FRAME* frame = chfl_frame();
CHFL_PROPERTY* property = chfl_property_double(-23);
chfl_frame_set_property(frame, "this", property);
chfl_property_free(property);
property = chfl_frame_get_property(frame, "this");
double value = 0;
chfl_property_get_double(property, &value);
assert(value == -23);
chfl_property_free(property);
chfl_frame_free(frame);
chfl_last_error
to learn about the error.
chfl_frame_free
(CHFL_FRAME *frame)¶Free the memory associated with a frame
.
CHFL_FRAME* frame = chfl_frame();
if (frame == NULL) {
/* handle error */
}
chfl_frame_free(frame);
CHFL_SUCCESS