/*! * \param[in,out] dest Destination data structure. * \param[in] src Source mapping. * \param[in] bFirst If true, memory is allocated for \p dest and a full * copy is made; otherwise, only variable parts are copied, and no memory * is allocated. * * \p dest should have been initialized somehow (calloc() is enough). */ void gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bFirst) { if (bFirst) { gmx_ana_indexmap_reserve(dest, src->b.nr, src->b.nra); dest->type = src->type; dest->b.nr = src->b.nr; dest->b.nra = src->b.nra; std::memcpy(dest->orgid, src->orgid, dest->b.nr*sizeof(*dest->orgid)); std::memcpy(dest->b.index, src->b.index, (dest->b.nr+1)*sizeof(*dest->b.index)); std::memcpy(dest->b.a, src->b.a, dest->b.nra*sizeof(*dest->b.a)); } dest->mapb.nr = src->mapb.nr; dest->mapb.nra = src->mapb.nra; if (src->mapb.nalloc_a > 0) { if (bFirst) { snew(dest->mapb.a, src->mapb.nalloc_a); dest->mapb.nalloc_a = src->mapb.nalloc_a; } std::memcpy(dest->mapb.a, src->mapb.a, dest->mapb.nra*sizeof(*dest->mapb.a)); } else { dest->mapb.a = src->mapb.a; } std::memcpy(dest->refid, src->refid, dest->mapb.nr*sizeof(*dest->refid)); std::memcpy(dest->mapid, src->mapid, dest->mapb.nr*sizeof(*dest->mapid)); std::memcpy(dest->mapb.index, src->mapb.index, (dest->mapb.nr+1)*sizeof(*dest->mapb.index)); dest->bStatic = src->bStatic; }
/*! * \param[in,out] pos Position data structure. * \param[in] n Maximum number of positions. * \param[in] isize Maximum number of atoms. * * Ensures that enough memory is allocated in \p pos to calculate \p n * positions from \p isize atoms. */ void gmx_ana_pos_reserve(gmx_ana_pos_t *pos, int n, int isize) { GMX_RELEASE_ASSERT(n >= 0, "Invalid position allocation count"); // Always reserve at least one entry to make NULL checks against pos->x // and gmx_ana_pos_reserve_velocities/forces() work as expected in the case // that there are actually no positions. if (n == 0) { n = 1; } if (pos->nalloc_x < n) { pos->nalloc_x = n; srenew(pos->x, n); if (pos->v) { srenew(pos->v, n); } if (pos->f) { srenew(pos->f, n); } } if (isize > 0) { gmx_ana_indexmap_reserve(&pos->m, n, isize); } }
/*! * \param[in,out] m Mapping structure to initialize. * \param[in] g Index group to map * (can be NULL if \p type is \ref INDEX_UNKNOWN). * \param[in] top Topology structure * (can be NULL if \p type is not \ref INDEX_RES or \ref INDEX_MOL). * \param[in] type Type of mapping to construct. * * Initializes a new index group mapping. * The index group provided to gmx_ana_indexmap_update() should always be a * subset of the \p g given here. * * \p m should have been initialized somehow (calloc() is enough). */ void gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, t_topology *top, e_index_t type) { int i, ii, mi; m->type = type; gmx_ana_index_make_block(&m->b, top, g, type, false); gmx_ana_indexmap_reserve(m, m->b.nr, m->b.nra); for (i = mi = 0; i < m->b.nr; ++i) { ii = (type == INDEX_UNKNOWN ? 0 : m->b.a[m->b.index[i]]); switch (type) { case INDEX_ATOM: m->orgid[i] = ii; break; case INDEX_RES: m->orgid[i] = top->atoms.atom[ii].resind; break; case INDEX_MOL: while (top->mols.index[mi+1] <= ii) { ++mi; } m->orgid[i] = mi; break; case INDEX_ALL: case INDEX_UNKNOWN: m->orgid[i] = 0; break; } } for (i = 0; i < m->b.nr; ++i) { m->refid[i] = i; m->mapid[i] = m->orgid[i]; } m->mapb.nr = m->b.nr; m->mapb.nra = m->b.nra; m->mapb.a = m->b.a; std::memcpy(m->mapb.index, m->b.index, (m->b.nr+1)*sizeof(*(m->mapb.index))); m->bStatic = true; }
/*! * \param[in,out] dest Destination data structure. * \param[in] src Source mapping. * \param[in] bFirst If TRUE, memory is allocated for \p dest and a full * copy is made; otherwise, only variable parts are copied, and no memory * is allocated. * * \p dest should have been initialized somehow (calloc() is enough). */ void gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bFirst) { if (bFirst) { gmx_ana_indexmap_reserve(dest, src->b.nr, src->b.nra); dest->type = src->type; dest->b.nr = src->b.nr; dest->b.nra = src->b.nra; dest->bStatic = src->bStatic; dest->bMapStatic = src->bMapStatic; memcpy(dest->orgid, src->orgid, dest->b.nr*sizeof(*dest->orgid)); memcpy(dest->b.index, src->b.index, (dest->b.nr+1)*sizeof(*dest->b.index)); memcpy(dest->b.a, src->b.a, dest->b.nra*sizeof(*dest->b.a)); } dest->nr = src->nr; dest->mapb.nr = src->mapb.nr; memcpy(dest->refid, src->refid, dest->nr*sizeof(*dest->refid)); memcpy(dest->mapid, src->mapid, dest->nr*sizeof(*dest->mapid)); memcpy(dest->mapb.index, src->mapb.index,(dest->mapb.nr+1)*sizeof(*dest->mapb.index)); }
/*! * \param[in,out] pos Position data structure. * \param[in] n Maximum number of positions. * \param[in] isize Maximum number of atoms. * * Ensures that enough memory is allocated in \p pos to calculate \p n * positions from \p isize atoms. */ void gmx_ana_pos_reserve(gmx_ana_pos_t *pos, int n, int isize) { if (pos->nalloc_x < n) { pos->nalloc_x = n; srenew(pos->x, n); if (pos->v) { srenew(pos->v, n); } if (pos->f) { srenew(pos->f, n); } } if (isize > 0) { gmx_ana_indexmap_reserve(&pos->m, n, isize); } }
/*! * \param[in,out] m Mapping structure to initialize. * \param[in] g Index group to map * (can be NULL if \p type is \ref INDEX_UNKNOWN). * \param[in] top Topology structure * (can be NULL if \p type is not \ref INDEX_RES or \ref INDEX_MOL). * \param[in] type Type of mapping to construct. * * Initializes a new index group mapping. * The index group provided to gmx_ana_indexmap_update() should always be a * subset of the \p g given here. * * \p m should have been initialized somehow (calloc() is enough). */ void gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, t_topology *top, e_index_t type) { m->type = type; gmx_ana_index_make_block(&m->b, top, g, type, false); gmx_ana_indexmap_reserve(m, m->b.nr, m->b.nra); int id = -1; for (int i = 0; i < m->b.nr; ++i) { const int ii = (type == INDEX_UNKNOWN ? 0 : m->b.a[m->b.index[i]]); next_group_index(ii, top, type, &id); m->refid[i] = i; m->mapid[i] = id; m->orgid[i] = id; } m->mapb.nr = m->b.nr; m->mapb.nra = m->b.nra; m->mapb.a = m->b.a; std::memcpy(m->mapb.index, m->b.index, (m->b.nr+1)*sizeof(*(m->mapb.index))); m->bStatic = true; }