/*!
 * \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;
}
예제 #2
0
/*!
 * \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;
}
예제 #4
0
/*!
 * \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));
}
예제 #5
0
/*!
 * \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);
    }
}
예제 #6
0
/*!
 * \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;
}