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_frame_copy
(const CHFL_FRAME *const 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_frame_atoms_count
(const CHFL_FRAME *const frame, uint64_t *natoms)¶Get the current number of atoms in a `frame` in the integer pointed to by `natoms`
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_frame_resize
(CHFL_FRAME *const frame, uint64_t natoms)¶Resize the positions, velocities and topology in the `frame`, to have space for `natoms` 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_frame_add_atom
(CHFL_FRAME *const frame, const CHFL_ATOM *const atom, const chfl_vector_t position, const chfl_vector_t 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_vector_t){1, 2, 3}, NULL);
chfl_atom_free(atom);
chfl_frame_free(frame);
chfl_frame_remove
(CHFL_FRAME *const 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_frame_positions
(CHFL_FRAME *const frame, chfl_vector_t **positions, uint64_t *size)¶Get a pointer to the positions array from a `frame`.
Positions are stored as a `natoms 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`), 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_vector_t* 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_frame_velocities
(CHFL_FRAME *const frame, chfl_vector_t **velocities, uint64_t *size)¶Get a pointer to the velocities array from a `frame`.
Velocities are stored as a `natoms 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`), 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 do 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_vector_t* 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_frame_has_velocities
(const CHFL_FRAME *const 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_frame_add_velocities
(CHFL_FRAME *const frame)¶Add velocity data to this `frame`.
The velocities ar initialized to `(chfl_vector_t){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_frame_set_cell
(CHFL_FRAME *const frame, const CHFL_CELL *const cell)¶Set the unit cell of a `frame` to `cell`.
CHFL_FRAME* frame = chfl_frame();
CHFL_CELL* cell = chfl_cell((chfl_vector_t){10, 10, 12});
chfl_frame_set_cell(frame, cell);
chfl_cell_free(cell);
chfl_frame_free(frame);
chfl_frame_set_topology
(CHFL_FRAME *const frame, const CHFL_TOPOLOGY *const 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_frame_step
(const CHFL_FRAME *const 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_frame_set_step
(CHFL_FRAME *const 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_frame_guess_topology
(CHFL_FRAME *const 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_vector_t){0, 0, 0}, NULL);
chfl_frame_add_atom(frame, Cl, (chfl_vector_t){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_frame_free
(CHFL_FRAME *const frame)¶Free the memory associated with a `frame`.
CHFL_FRAME* frame = chfl_frame();
if (frame == NULL) {
/* handle error */
}
chfl_frame_free(frame);