/*! * \param[out] g Index group structure. * \param[in] top Topology structure. * \param[in] fnm File name for the index file. * Memory is automatically allocated. * * One or both of \p top or \p fnm can be NULL. * If \p top is NULL, an index file is required and the groups are read * from the file (uses Gromacs routine init_index()). * If \p fnm is NULL, default groups are constructed based on the * topology (uses Gromacs routine analyse()). * If both are null, the index group structure is initialized empty. */ void gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, t_topology *top, const char *fnm) { t_blocka *block = NULL; char **names = NULL; if (fnm) { block = init_index(fnm, &names); } else if (top) { block = new_blocka(); analyse(&top->atoms, block, &names, FALSE, FALSE); } else { *g = new gmx_ana_indexgrps_t(0); return; } try { *g = new gmx_ana_indexgrps_t(block->nr); for (int i = 0; i < block->nr; ++i) { gmx_ana_index_t *grp = &(*g)->g[i]; grp->isize = block->index[i+1] - block->index[i]; snew(grp->index, grp->isize); for (int j = 0; j < grp->isize; ++j) { grp->index[j] = block->a[block->index[i]+j]; } grp->nalloc_index = grp->isize; (*g)->names.push_back(names[i]); } } catch (...) { for (int i = 0; i < block->nr; ++i) { sfree(names[i]); } sfree(names); done_blocka(block); sfree(block); throw; } for (int i = 0; i < block->nr; ++i) { sfree(names[i]); } sfree(names); done_blocka(block); sfree(block); }
void chk_ndx(const char *fn) { t_blocka *grps; char **grpname; int i, j; grps = init_index(fn, &grpname); if (debug) { pr_blocka(debug, 0, fn, grps, FALSE); } else { printf("Contents of index file %s\n", fn); printf("--------------------------------------------------\n"); printf("Nr. Group #Entries First Last\n"); for (i = 0; (i < grps->nr); i++) { printf("%4d %-20s%8d%8d%8d\n", i, grpname[i], grps->index[i+1]-grps->index[i], grps->a[grps->index[i]]+1, grps->a[grps->index[i+1]-1]+1); } } for (i = 0; (i < grps->nr); i++) { sfree(grpname[i]); } sfree(grpname); done_blocka(grps); }
static real constr_r_max_moltype(FILE *fplog, gmx_moltype_t *molt,t_iparams *iparams, t_inputrec *ir) { int natoms,nflexcon,*path,at,count; t_blocka at2con; real r0,r1,r2maxA,r2maxB,rmax,lam0,lam1; if (molt->ilist[F_CONSTR].nr == 0 && molt->ilist[F_CONSTRNC].nr == 0) { return 0; } natoms = molt->atoms.nr; at2con = make_at2con(0,natoms,molt->ilist,iparams, EI_DYNAMICS(ir->eI),&nflexcon); snew(path,1+ir->nProjOrder); for(at=0; at<1+ir->nProjOrder; at++) path[at] = -1; r2maxA = 0; for(at=0; at<natoms; at++) { r0 = 0; r1 = 0; count = 0; constr_recur(&at2con,molt->ilist,iparams, FALSE,at,0,1+ir->nProjOrder,path,r0,r1,&r2maxA,&count); } if (ir->efep == efepNO) { rmax = sqrt(r2maxA); } else { r2maxB = 0; for(at=0; at<natoms; at++) { r0 = 0; r1 = 0; count = 0; constr_recur(&at2con,molt->ilist,iparams, TRUE,at,0,1+ir->nProjOrder,path,r0,r1,&r2maxB,&count); } lam0 = ir->init_lambda; if (EI_DYNAMICS(ir->eI)) lam0 += ir->init_step*ir->delta_lambda; rmax = (1 - lam0)*sqrt(r2maxA) + lam0*sqrt(r2maxB); if (EI_DYNAMICS(ir->eI)) { lam1 = ir->init_lambda + (ir->init_step + ir->nsteps)*ir->delta_lambda; rmax = max(rmax,(1 - lam1)*sqrt(r2maxA) + lam1*sqrt(r2maxB)); } } done_blocka(&at2con); sfree(path); return rmax; }
void done_moltype(gmx_moltype_t *molt) { done_atom(&molt->atoms); done_block(&molt->cgs); done_blocka(&molt->excls); for (int f = 0; f < F_NRE; f++) { sfree(molt->ilist[f].iatoms); molt->ilist[f].nalloc = 0; } }
void done_top(t_topology *top) { int i; done_atom (&(top->atoms)); /* For GB */ done_atomtypes(&(top->atomtypes)); done_symtab(&(top->symtab)); done_block(&(top->cgs)); done_block(&(top->mols)); done_blocka(&(top->excls)); }
/*! * \param[out] g Index group structure. * \param[in] top Topology structure. * \param[in] fnm File name for the index file. * Memory is automatically allocated. * * One or both of \p top or \p fnm can be NULL. * If \p top is NULL, an index file is required and the groups are read * from the file (uses Gromacs routine init_index()). * If \p fnm is NULL, default groups are constructed based on the * topology (uses Gromacs routine analyse()). * If both are null, the index group structure is initialized empty. */ void gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, t_topology *top, const char *fnm) { t_blocka *block = NULL; char **names = NULL; int i, j; if (fnm) { block = init_index(fnm, &names); } else if (top) { block = new_blocka(); analyse(&top->atoms, block, &names, FALSE, FALSE); } else { snew(*g, 1); (*g)->nr = 0; (*g)->g = NULL; return; } gmx_ana_indexgrps_alloc(g, block->nr); for (i = 0; i < block->nr; ++i) { gmx_ana_index_t *grp = &(*g)->g[i]; grp->isize = block->index[i+1] - block->index[i]; snew(grp->index, grp->isize); for (j = 0; j < grp->isize; ++j) { grp->index[j] = block->a[block->index[i]+j]; } grp->name = names[i]; grp->nalloc_index = grp->isize; } done_blocka(block); sfree(block); sfree(names); }
void done_top(t_topology *top) { sfree(top->idef.functype); sfree(top->idef.iparams); for (int f = 0; f < F_NRE; ++f) { sfree(top->idef.il[f].iatoms); top->idef.il[f].iatoms = NULL; top->idef.il[f].nalloc = 0; } done_atom(&(top->atoms)); /* For GB */ done_atomtypes(&(top->atomtypes)); done_symtab(&(top->symtab)); done_block(&(top->cgs)); done_block(&(top->mols)); done_blocka(&(top->excls)); }
static void make_shake_sblock_serial(struct gmx_constr *constr, t_idef *idef, t_mdatoms *md) { int i, j, m, ncons; int bstart, bnr; t_blocka sblocks; t_sortblock *sb; t_iatom *iatom; atom_id *inv_sblock; /* Since we are processing the local topology, * the F_CONSTRNC ilist has been concatenated to the F_CONSTR ilist. */ ncons = idef->il[F_CONSTR].nr/3; init_blocka(&sblocks); gen_sblocks(NULL, 0, md->homenr, idef, &sblocks, FALSE); /* bstart=(idef->nodeid > 0) ? blocks->multinr[idef->nodeid-1] : 0; nblocks=blocks->multinr[idef->nodeid] - bstart; */ bstart = 0; constr->nblocks = sblocks.nr; if (debug) { fprintf(debug, "ncons: %d, bstart: %d, nblocks: %d\n", ncons, bstart, constr->nblocks); } /* Calculate block number for each atom */ inv_sblock = make_invblocka(&sblocks, md->nr); done_blocka(&sblocks); /* Store the block number in temp array and * sort the constraints in order of the sblock number * and the atom numbers, really sorting a segment of the array! */ #ifdef DEBUGIDEF pr_idef(fplog, 0, "Before Sort", idef); #endif iatom = idef->il[F_CONSTR].iatoms; snew(sb, ncons); for (i = 0; (i < ncons); i++, iatom += 3) { for (m = 0; (m < 3); m++) { sb[i].iatom[m] = iatom[m]; } sb[i].blocknr = inv_sblock[iatom[1]]; } /* Now sort the blocks */ if (debug) { pr_sortblock(debug, "Before sorting", ncons, sb); fprintf(debug, "Going to sort constraints\n"); } qsort(sb, ncons, (size_t)sizeof(*sb), pcomp); if (debug) { pr_sortblock(debug, "After sorting", ncons, sb); } iatom = idef->il[F_CONSTR].iatoms; for (i = 0; (i < ncons); i++, iatom += 3) { for (m = 0; (m < 3); m++) { iatom[m] = sb[i].iatom[m]; } } #ifdef DEBUGIDEF pr_idef(fplog, 0, "After Sort", idef); #endif j = 0; snew(constr->sblock, constr->nblocks+1); bnr = -2; for (i = 0; (i < ncons); i++) { if (sb[i].blocknr != bnr) { bnr = sb[i].blocknr; constr->sblock[j++] = 3*i; } } /* Last block... */ constr->sblock[j++] = 3*ncons; if (j != (constr->nblocks+1)) { fprintf(stderr, "bstart: %d\n", bstart); fprintf(stderr, "j: %d, nblocks: %d, ncons: %d\n", j, constr->nblocks, ncons); for (i = 0; (i < ncons); i++) { fprintf(stderr, "i: %5d sb[i].blocknr: %5u\n", i, sb[i].blocknr); } for (j = 0; (j <= constr->nblocks); j++) { fprintf(stderr, "sblock[%3d]=%5d\n", j, (int)constr->sblock[j]); } gmx_fatal(FARGS, "DEATH HORROR: " "sblocks does not match idef->il[F_CONSTR]"); } sfree(sb); sfree(inv_sblock); }
void set_lincs(t_idef *idef,t_mdatoms *md, gmx_bool bDynamics,t_commrec *cr, struct gmx_lincsdata *li) { int start,natoms,nflexcon; t_blocka at2con; t_iatom *iatom; int i,k,ncc_alloc,ni,con,nconnect,concon; int type,a1,a2; real lenA=0,lenB; gmx_bool bLocal; li->nc = 0; li->ncc = 0; /* This is the local topology, so there are only F_CONSTR constraints */ if (idef->il[F_CONSTR].nr == 0) { /* There are no constraints, * we do not need to fill any data structures. */ return; } if (debug) { fprintf(debug,"Building the LINCS connectivity\n"); } if (DOMAINDECOMP(cr)) { if (cr->dd->constraints) { dd_get_constraint_range(cr->dd,&start,&natoms); } else { natoms = cr->dd->nat_home; } start = 0; } else if(PARTDECOMP(cr)) { pd_get_constraint_range(cr->pd,&start,&natoms); } else { start = md->start; natoms = md->homenr; } at2con = make_at2con(start,natoms,idef->il,idef->iparams,bDynamics, &nflexcon); if (idef->il[F_CONSTR].nr/3 > li->nc_alloc || li->nc_alloc == 0) { li->nc_alloc = over_alloc_dd(idef->il[F_CONSTR].nr/3); srenew(li->bllen0,li->nc_alloc); srenew(li->ddist,li->nc_alloc); srenew(li->bla,2*li->nc_alloc); srenew(li->blc,li->nc_alloc); srenew(li->blc1,li->nc_alloc); srenew(li->blnr,li->nc_alloc+1); srenew(li->bllen,li->nc_alloc); srenew(li->tmpv,li->nc_alloc); srenew(li->tmp1,li->nc_alloc); srenew(li->tmp2,li->nc_alloc); srenew(li->tmp3,li->nc_alloc); srenew(li->lambda,li->nc_alloc); if (li->ncg_triangle > 0) { /* This is allocating too much, but it is difficult to improve */ srenew(li->triangle,li->nc_alloc); srenew(li->tri_bits,li->nc_alloc); } } iatom = idef->il[F_CONSTR].iatoms; ncc_alloc = li->ncc_alloc; li->blnr[0] = 0; ni = idef->il[F_CONSTR].nr/3; con = 0; nconnect = 0; li->blnr[con] = nconnect; for(i=0; i<ni; i++) { bLocal = TRUE; type = iatom[3*i]; a1 = iatom[3*i+1]; a2 = iatom[3*i+2]; lenA = idef->iparams[type].constr.dA; lenB = idef->iparams[type].constr.dB; /* Skip the flexible constraints when not doing dynamics */ if (bDynamics || lenA!=0 || lenB!=0) { li->bllen0[con] = lenA; li->ddist[con] = lenB - lenA; /* Set the length to the topology A length */ li->bllen[con] = li->bllen0[con]; li->bla[2*con] = a1; li->bla[2*con+1] = a2; /* Construct the constraint connection matrix blbnb */ for(k=at2con.index[a1-start]; k<at2con.index[a1-start+1]; k++) { concon = at2con.a[k]; if (concon != i) { if (nconnect >= ncc_alloc) { ncc_alloc = over_alloc_small(nconnect+1); srenew(li->blbnb,ncc_alloc); } li->blbnb[nconnect++] = concon; } } for(k=at2con.index[a2-start]; k<at2con.index[a2-start+1]; k++) { concon = at2con.a[k]; if (concon != i) { if (nconnect+1 > ncc_alloc) { ncc_alloc = over_alloc_small(nconnect+1); srenew(li->blbnb,ncc_alloc); } li->blbnb[nconnect++] = concon; } } li->blnr[con+1] = nconnect; if (cr->dd == NULL) { /* Order the blbnb matrix to optimize memory access */ qsort(&(li->blbnb[li->blnr[con]]),li->blnr[con+1]-li->blnr[con], sizeof(li->blbnb[0]),int_comp); } /* Increase the constraint count */ con++; } } done_blocka(&at2con); /* This is the real number of constraints, * without dynamics the flexible constraints are not present. */ li->nc = con; li->ncc = li->blnr[con]; if (cr->dd == NULL) { /* Since the matrix is static, we can free some memory */ ncc_alloc = li->ncc; srenew(li->blbnb,ncc_alloc); } if (ncc_alloc > li->ncc_alloc) { li->ncc_alloc = ncc_alloc; srenew(li->blmf,li->ncc_alloc); srenew(li->blmf1,li->ncc_alloc); srenew(li->tmpncc,li->ncc_alloc); } if (debug) { fprintf(debug,"Number of constraints is %d, couplings %d\n", li->nc,li->ncc); } set_lincs_matrix(li,md->invmass,md->lambda); }
void set_histp(t_atoms *pdba, rvec *x, real angle, real dist) { static const char *prot_acc[] = { "O", "OD1", "OD2", "OE1", "OE2", "OG", "OG1", "OH", "OW" }; #define NPA asize(prot_acc) static const char *prot_don[] = { "N", "NH1", "NH2", "NE", "ND1", "ND2", "NE2", "NZ", "OG", "OG1", "OH", "NE1", "OW" }; #define NPD asize(prot_don) gmx_bool *donor, *acceptor; gmx_bool *hbond; gmx_bool bHDd, bHEd; rvec xh1, xh2; int natom; int i, j, nd, na, hisind, type = -1; int nd1, ne2, cg, cd2, ce1; t_blocka *hb; char *atomnm; natom = pdba->nr; i = 0; while (i < natom && gmx_strcasecmp(*pdba->resinfo[pdba->atom[i].resind].name, "HIS") != 0) { i++; } if (natom == i) { return; } /* A histidine residue exists that requires automated assignment, so * doing the analysis of donors and acceptors is worthwhile. */ fprintf(stderr, "Analysing hydrogen-bonding network for automated assignment of histidine\n" " protonation."); snew(donor, natom); snew(acceptor, natom); snew(hbond, natom); snew(hb, 1); nd = na = 0; for (j = 0; (j < natom); j++) { if (in_strings(*pdba->atomname[j], NPA, prot_acc) != -1) { acceptor[j] = TRUE; na++; } if (in_strings(*pdba->atomname[j], NPD, prot_don) != -1) { donor[j] = TRUE; nd++; } } fprintf(stderr, " %d donors and %d acceptors were found.\n", nd, na); chk_allhb(pdba, x, hb, donor, acceptor, dist); if (debug) { pr_hbonds(debug, hb, pdba); } fprintf(stderr, "There are %d hydrogen bonds\n", hb->nra); /* Now do the HIS stuff */ hisind = -1; while (i < natom) { if (gmx_strcasecmp(*pdba->resinfo[pdba->atom[i].resind].name, "HIS") != 0) { i++; } else { if (pdba->atom[i].resind != hisind) { hisind = pdba->atom[i].resind; /* Find the atoms in the ring */ nd1 = ne2 = cg = cd2 = ce1 = -1; while (i < natom && pdba->atom[i].resind == hisind) { atomnm = *pdba->atomname[i]; if (strcmp(atomnm, "CD2") == 0) { cd2 = i; } else if (strcmp(atomnm, "CG") == 0) { cg = i; } else if (strcmp(atomnm, "CE1") == 0) { ce1 = i; } else if (strcmp(atomnm, "ND1") == 0) { nd1 = i; } else if (strcmp(atomnm, "NE2") == 0) { ne2 = i; } i++; } if (!((cg == -1 ) || (cd2 == -1) || (ce1 == -1) || (nd1 == -1) || (ne2 == -1))) { calc_ringh(x[nd1], x[cg], x[ce1], xh1); calc_ringh(x[ne2], x[ce1], x[cd2], xh2); bHDd = chk_hbonds(nd1, pdba, x, acceptor, hbond, xh1, angle, dist); chk_hbonds(nd1, pdba, x, donor, hbond, xh1, angle, dist); bHEd = chk_hbonds(ne2, pdba, x, acceptor, hbond, xh2, angle, dist); chk_hbonds(ne2, pdba, x, donor, hbond, xh2, angle, dist); if (bHDd) { if (bHEd) { type = ehisH; } else { type = ehisA; } } else { type = ehisB; } fprintf(stderr, "Will use %s for residue %d\n", hh[type], pdba->resinfo[hisind].nr); } else { gmx_fatal(FARGS, "Incomplete ring in HIS%d", pdba->resinfo[hisind].nr); } snew(pdba->resinfo[hisind].rtp, 1); *pdba->resinfo[hisind].rtp = gmx_strdup(hh[type]); } } } done_blocka(hb); sfree(hb); sfree(donor); sfree(acceptor); sfree(hbond); }