int dd_make_local_vsites(gmx_domdec_t *dd, int at_start, t_ilist *lil) { gmx_domdec_specat_comm_t *spac; ind_req_t *ireq; gmx_hash_t ga2la_specat; int ftype, nral, i, j, a; t_ilist *lilf; t_iatom *iatoms; int at_end; spac = dd->vsite_comm; ireq = &spac->ireq[0]; ga2la_specat = dd->ga2la_vsite; ireq->n = 0; /* Loop over all the home vsites */ for (ftype = 0; ftype < F_NRE; ftype++) { if (interaction_function[ftype].flags & IF_VSITE) { nral = NRAL(ftype); lilf = &lil[ftype]; for (i = 0; i < lilf->nr; i += 1+nral) { iatoms = lilf->iatoms + i; /* Check if we have the other atoms */ for (j = 1; j < 1+nral; j++) { if (iatoms[j] < 0) { /* This is not a home atom, * we need to ask our neighbors. */ a = -iatoms[j] - 1; /* Check to not ask for the same atom more than once */ if (gmx_hash_get_minone(dd->ga2la_vsite, a) == -1) { /* Add this non-home atom to the list */ if (ireq->n+1 > ireq->nalloc) { ireq->nalloc = over_alloc_large(ireq->n+1); srenew(ireq->ind, ireq->nalloc); } ireq->ind[ireq->n++] = a; /* Temporarily mark with -2, * we get the index later. */ gmx_hash_set(ga2la_specat, a, -2); } } } } } } at_end = setup_specat_communication(dd, ireq, dd->vsite_comm, ga2la_specat, at_start, 1, "vsite", ""); /* Fill in the missing indices */ for (ftype = 0; ftype < F_NRE; ftype++) { if (interaction_function[ftype].flags & IF_VSITE) { nral = NRAL(ftype); lilf = &lil[ftype]; for (i = 0; i < lilf->nr; i += 1+nral) { iatoms = lilf->iatoms + i; for (j = 1; j < 1+nral; j++) { if (iatoms[j] < 0) { iatoms[j] = gmx_hash_get_minone(ga2la_specat, -iatoms[j]-1); } } } } } return at_end; }
/*! \brief Walks over the constraints out from the local atoms into the non-local atoms and adds them to a list */ static void walk_out(int con, int con_offset, int a, int offset, int nrec, int ncon1, const t_iatom *ia1, const t_iatom *ia2, const t_blocka *at2con, const gmx_ga2la_t *ga2la, gmx_bool bHomeConnect, gmx_domdec_constraints_t *dc, gmx_domdec_specat_comm_t *dcc, t_ilist *il_local, ind_req_t *ireq) { int a1_gl, a2_gl, a_loc, i, coni, b; const t_iatom *iap; if (dc->gc_req[con_offset+con] == 0) { /* Add this non-home constraint to the list */ if (dc->ncon+1 > dc->con_nalloc) { dc->con_nalloc = over_alloc_large(dc->ncon+1); srenew(dc->con_gl, dc->con_nalloc); srenew(dc->con_nlocat, dc->con_nalloc); } dc->con_gl[dc->ncon] = con_offset + con; dc->con_nlocat[dc->ncon] = (bHomeConnect ? 1 : 0); dc->gc_req[con_offset+con] = 1; if (il_local->nr + 3 > il_local->nalloc) { il_local->nalloc = over_alloc_dd(il_local->nr+3); srenew(il_local->iatoms, il_local->nalloc); } iap = constr_iatomptr(ncon1, ia1, ia2, con); il_local->iatoms[il_local->nr++] = iap[0]; a1_gl = offset + iap[1]; a2_gl = offset + iap[2]; /* The following indexing code can probably be optizimed */ if (ga2la_get_home(ga2la, a1_gl, &a_loc)) { il_local->iatoms[il_local->nr++] = a_loc; } else { /* We set this index later */ il_local->iatoms[il_local->nr++] = -a1_gl - 1; } if (ga2la_get_home(ga2la, a2_gl, &a_loc)) { il_local->iatoms[il_local->nr++] = a_loc; } else { /* We set this index later */ il_local->iatoms[il_local->nr++] = -a2_gl - 1; } dc->ncon++; } /* Check to not ask for the same atom more than once */ if (gmx_hash_get_minone(dc->ga2la, offset+a) == -1) { assert(dcc); /* Add this non-home atom to the list */ if (ireq->n+1 > ireq->nalloc) { ireq->nalloc = over_alloc_large(ireq->n+1); srenew(ireq->ind, ireq->nalloc); } ireq->ind[ireq->n++] = offset + a; /* Temporarily mark with -2, we get the index later */ gmx_hash_set(dc->ga2la, offset+a, -2); } if (nrec > 0) { for (i = at2con->index[a]; i < at2con->index[a+1]; i++) { coni = at2con->a[i]; if (coni != con) { /* Walk further */ iap = constr_iatomptr(ncon1, ia1, ia2, coni); if (a == iap[1]) { b = iap[2]; } else { b = iap[1]; } if (!ga2la_get_home(ga2la, offset+b, &a_loc)) { walk_out(coni, con_offset, b, offset, nrec-1, ncon1, ia1, ia2, at2con, ga2la, FALSE, dc, dcc, il_local, ireq); } } } } }