/*! * \param[in] pc Position calculation data. * \param[in,out] p Output positions, initialized previously with * gmx_ana_poscalc_init_pos() using \p pc. * \param[in] g Index group to use for the update. * \param[in] x Current positions of the atoms. * \param[in] pbc PBC data, or NULL if no PBC should be used. * * gmx_ana_poscalc_init_frame() should be called for each frame before calling * this function. */ void gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, gmx_ana_index_t *g, rvec x[], t_pbc *pbc) { int i, j, bi, bj; if (pc->bEval == TRUE && !(pc->flags & POS_MASKONLY)) { return; } if (pc->sbase) { gmx_ana_poscalc_update(pc->sbase, NULL, NULL, x, pbc); } if (!p) { p = pc->p; } if (!g) { g = &pc->gmax; } p->g = g; /* Update the index map */ if (pc->flags & POS_DYNAMIC) { gmx_ana_indexmap_update(&p->m, g, FALSE); p->nr = p->m.nr; } else if (pc->flags & POS_MASKONLY) { gmx_ana_indexmap_update(&p->m, g, TRUE); if (pc->bEval) return; } if (!(pc->flags & POS_DYNAMIC)) { pc->bEval = TRUE; } /* Evaluate the positions */ if (pc->sbase) { /* TODO: It might be faster to evaluate the positions within this * loop instead of in the beginning. */ if (pc->flags & POS_DYNAMIC) { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[p->m.refid[bi]]; copy_rvec(pc->sbase->p->x[bj], p->x[bi]); } } else { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[bi]; copy_rvec(pc->sbase->p->x[bj], p->x[bi]); } } } else /* pc->sbase is NULL */ { if (pc->flags & POS_DYNAMIC) { pc->b.nr = p->m.mapb.nr; pc->b.index = p->m.mapb.index; pc->b.nra = g->isize; pc->b.a = g->index; } /* Here, we assume that the topology has been properly initialized, * and do not check the return values of gmx_calc_comg*(). */ switch (pc->type) { case POS_ATOM: for (i = 0; i < pc->b.nra; ++i) { copy_rvec(x[pc->b.a[i]], p->x[i]); } break; case POS_ALL: gmx_calc_comg(pc->coll->top, x, pc->b.nra, pc->b.a, pc->flags & POS_MASS, p->x[0]); break; case POS_ALL_PBC: gmx_calc_comg_pbc(pc->coll->top, x, pbc, pc->b.nra, pc->b.a, pc->flags & POS_MASS, p->x[0]); break; default: gmx_calc_comg_blocka(pc->coll->top, x, &pc->b, pc->flags & POS_MASS, p->x); break; } } }
/*! * \param[in] pc Position calculation data. * \param[in,out] p Output positions, initialized previously with * gmx_ana_poscalc_init_pos() using \p pc. * \param[in] g Index group to use for the update. * \param[in] fr Current frame. * \param[in] pbc PBC data, or NULL if no PBC should be used. * * gmx_ana_poscalc_init_frame() should be called for each frame before calling * this function. */ void gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, gmx_ana_index_t *g, t_trxframe *fr, t_pbc *pbc) { int i, bi, bj; if (pc->bEval == true && !(pc->flags & POS_MASKONLY)) { return; } if (pc->sbase) { gmx_ana_poscalc_update(pc->sbase, NULL, NULL, fr, pbc); } if (!p) { p = pc->p; } if (!g) { g = &pc->gmax; } gmx_ana_pos_set_evalgrp(p, g); /* Update the index map */ if (pc->flags & POS_DYNAMIC) { gmx_ana_indexmap_update(&p->m, g, false); p->nr = p->m.nr; } else if (pc->flags & POS_MASKONLY) { gmx_ana_indexmap_update(&p->m, g, true); if (pc->bEval) { return; } } if (!(pc->flags & POS_DYNAMIC)) { pc->bEval = true; } /* Evaluate the positions */ if (pc->sbase) { /* TODO: It might be faster to evaluate the positions within this * loop instead of in the beginning. */ if (pc->flags & POS_DYNAMIC) { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[p->m.refid[bi]]; copy_rvec(pc->sbase->p->x[bj], p->x[bi]); } if (p->v) { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[p->m.refid[bi]]; copy_rvec(pc->sbase->p->v[bj], p->v[bi]); } } if (p->f) { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[p->m.refid[bi]]; copy_rvec(pc->sbase->p->f[bj], p->f[bi]); } } } else { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[bi]; copy_rvec(pc->sbase->p->x[bj], p->x[bi]); } if (p->v) { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[bi]; copy_rvec(pc->sbase->p->v[bj], p->v[bi]); } } if (p->f) { for (bi = 0; bi < p->nr; ++bi) { bj = pc->baseid[bi]; copy_rvec(pc->sbase->p->f[bj], p->f[bi]); } } } } else /* pc->sbase is NULL */ { if (pc->flags & POS_DYNAMIC) { pc->b.nr = p->m.mapb.nr; pc->b.index = p->m.mapb.index; pc->b.nra = g->isize; pc->b.a = g->index; } if (p->v && !fr->bV) { for (i = 0; i < pc->b.nra; ++i) { clear_rvec(p->v[i]); } } if (p->f && !fr->bF) { for (i = 0; i < pc->b.nra; ++i) { clear_rvec(p->f[i]); } } /* Here, we assume that the topology has been properly initialized, * and do not check the return values of gmx_calc_comg*(). */ t_topology *top = pc->coll->top_; bool bMass = pc->flags & POS_MASS; switch (pc->type) { case POS_ATOM: for (i = 0; i < pc->b.nra; ++i) { copy_rvec(fr->x[pc->b.a[i]], p->x[i]); } if (p->v && fr->bV) { for (i = 0; i < pc->b.nra; ++i) { copy_rvec(fr->v[pc->b.a[i]], p->v[i]); } } if (p->f && fr->bF) { for (i = 0; i < pc->b.nra; ++i) { copy_rvec(fr->f[pc->b.a[i]], p->f[i]); } } break; case POS_ALL: gmx_calc_comg(top, fr->x, pc->b.nra, pc->b.a, bMass, p->x[0]); if (p->v && fr->bV) { gmx_calc_comg(top, fr->v, pc->b.nra, pc->b.a, bMass, p->v[0]); } if (p->f && fr->bF) { gmx_calc_comg_f(top, fr->f, pc->b.nra, pc->b.a, bMass, p->f[0]); } break; case POS_ALL_PBC: gmx_calc_comg_pbc(top, fr->x, pbc, pc->b.nra, pc->b.a, bMass, p->x[0]); if (p->v && fr->bV) { gmx_calc_comg(top, fr->v, pc->b.nra, pc->b.a, bMass, p->v[0]); } if (p->f && fr->bF) { gmx_calc_comg_f(top, fr->f, pc->b.nra, pc->b.a, bMass, p->f[0]); } break; default: gmx_calc_comg_blocka(top, fr->x, &pc->b, bMass, p->x); if (p->v && fr->bV) { gmx_calc_comg_blocka(top, fr->v, &pc->b, bMass, p->v); } if (p->f && fr->bF) { gmx_calc_comg_blocka(top, fr->f, &pc->b, bMass, p->f); } break; } } }