void make_local_shells(t_commrec *cr,t_mdatoms *md, struct gmx_shellfc *shfc) { t_shell *shell; int a0,a1,*ind,nshell,i; gmx_domdec_t *dd=NULL; if (PAR(cr)) { if (DOMAINDECOMP(cr)) { dd = cr->dd; a0 = 0; a1 = dd->nat_home; } else { pd_at_range(cr,&a0,&a1); } } else { /* Single node: we need all shells, just copy the pointer */ shfc->nshell = shfc->nshell_gl; shfc->shell = shfc->shell_gl; return; } ind = shfc->shell_index_gl; nshell = 0; shell = shfc->shell; for(i=a0; i<a1; i++) { if (md->ptype[i] == eptShell) { if (nshell+1 > shfc->shell_nalloc) { shfc->shell_nalloc = over_alloc_dd(nshell+1); srenew(shell,shfc->shell_nalloc); } if (dd) { shell[nshell] = shfc->shell_gl[ind[dd->gatindex[i]]]; } else { shell[nshell] = shfc->shell_gl[ind[i]]; } /* With inter-cg shells we can no do shell prediction, * so we do not need the nuclei numbers. */ if (!shfc->bInterCG) { shell[nshell].nucl1 = i + shell[nshell].nucl1 - shell[nshell].shell; if (shell[nshell].nnucl > 1) shell[nshell].nucl2 = i + shell[nshell].nucl2 - shell[nshell].shell; if (shell[nshell].nnucl > 2) shell[nshell].nucl3 = i + shell[nshell].nucl3 - shell[nshell].shell; } shell[nshell].shell = i; nshell++; } } shfc->nshell = nshell; shfc->shell = shell; }
void init_pull(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], gmx_mtop_t *mtop, t_commrec *cr, const output_env_t oenv, real lambda, gmx_bool bOutFile, unsigned long Flags) { t_pull *pull; t_pull_group *pgrp; int c, g, start = 0, end = 0, m; pull = ir->pull; pull->ePBC = ir->ePBC; switch (pull->ePBC) { case epbcNONE: pull->npbcdim = 0; break; case epbcXY: pull->npbcdim = 2; break; default: pull->npbcdim = 3; break; } if (fplog) { gmx_bool bAbs, bCos; bAbs = FALSE; for (c = 0; c < pull->ncoord; c++) { if (pull->group[pull->coord[c].group[0]].nat == 0 || pull->group[pull->coord[c].group[1]].nat == 0) { bAbs = TRUE; } } fprintf(fplog, "\nWill apply %s COM pulling in geometry '%s'\n", EPULLTYPE(ir->ePull), EPULLGEOM(pull->eGeom)); fprintf(fplog, "with %d pull coordinate%s and %d group%s\n", pull->ncoord, pull->ncoord == 1 ? "" : "s", pull->ngroup, pull->ngroup == 1 ? "" : "s"); if (bAbs) { fprintf(fplog, "with an absolute reference\n"); } bCos = FALSE; for (g = 0; g < pull->ngroup; g++) { if (pull->group[g].nat > 1 && pull->group[g].pbcatom < 0) { /* We are using cosine weighting */ fprintf(fplog, "Cosine weighting is used for group %d\n", g); bCos = TRUE; } } if (bCos) { please_cite(fplog, "Engin2010"); } } /* We always add the virial contribution, * except for geometry = direction_periodic where this is impossible. */ pull->bVirial = (pull->eGeom != epullgDIRPBC); if (getenv("GMX_NO_PULLVIR") != NULL) { if (fplog) { fprintf(fplog, "Found env. var., will not add the virial contribution of the COM pull forces\n"); } pull->bVirial = FALSE; } if (cr && PARTDECOMP(cr)) { pd_at_range(cr, &start, &end); } pull->rbuf = NULL; pull->dbuf = NULL; pull->dbuf_cyl = NULL; pull->bRefAt = FALSE; pull->cosdim = -1; for (g = 0; g < pull->ngroup; g++) { pgrp = &pull->group[g]; pgrp->epgrppbc = epgrppbcNONE; if (pgrp->nat > 0) { /* Determine if we need to take PBC into account for calculating * the COM's of the pull groups. */ for (m = 0; m < pull->npbcdim; m++) { if (pull->dim[m] && pgrp->nat > 1) { if (pgrp->pbcatom >= 0) { pgrp->epgrppbc = epgrppbcREFAT; pull->bRefAt = TRUE; } else { if (pgrp->weight) { gmx_fatal(FARGS, "Pull groups can not have relative weights and cosine weighting at same time"); } pgrp->epgrppbc = epgrppbcCOS; if (pull->cosdim >= 0 && pull->cosdim != m) { gmx_fatal(FARGS, "Can only use cosine weighting with pulling in one dimension (use mdp option pull_dim)"); } pull->cosdim = m; } } } /* Set the indices */ init_pull_group_index(fplog, cr, start, end, g, pgrp, pull->dim, mtop, ir, lambda); if (PULL_CYL(pull) && pgrp->invtm == 0) { gmx_fatal(FARGS, "Can not have frozen atoms in a cylinder pull group"); } } else { /* Absolute reference, set the inverse mass to zero */ pgrp->invtm = 0; pgrp->wscale = 1; } } /* if we use dynamic reference groups, do some initialising for them */ if (PULL_CYL(pull)) { if (ir->ePull == epullCONSTRAINT && pull->ncoord > 1) { /* We can't easily update the single reference group with multiple * constraints. This would require recalculating COMs. */ gmx_fatal(FARGS, "Constraint COM pulling supports only one coordinate with geometry=cylinder, you can use umbrella pulling with multiple coordinates"); } for (c = 0; c < pull->ncoord; c++) { if (pull->group[pull->coord[c].group[0]].nat == 0) { gmx_fatal(FARGS, "Dynamic reference groups are not supported when using absolute reference!\n"); } } snew(pull->dyna, pull->ncoord); } /* Only do I/O when we are doing dynamics and if we are the MASTER */ pull->out_x = NULL; pull->out_f = NULL; if (bOutFile) { if (pull->nstxout > 0) { pull->out_x = open_pull_out(opt2fn("-px", nfile, fnm), pull, oenv, TRUE, Flags); } if (pull->nstfout > 0) { pull->out_f = open_pull_out(opt2fn("-pf", nfile, fnm), pull, oenv, FALSE, Flags); } } }