/*!
 * \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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
    }
}
Beispiel #5
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));
}
Beispiel #6
0
/*!
 * \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);
}
Beispiel #7
0
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));
}
Beispiel #8
0
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);
}
Beispiel #9
0
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);
}
Beispiel #10
0
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);
}