2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2008 David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
5 * Copyright (c) 2013, by the GROMACS development team, led by
6 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 * and including many others, as listed in the AUTHORS file in the
8 * top-level source directory and at http://www.gromacs.org.
10 * GROMACS is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (at your option) any later version.
15 * GROMACS is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with GROMACS; if not, see
22 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * If you want to redistribute modifications to GROMACS, please
26 * consider that scientific software is very special. Version
27 * control is crucial - bugs must be traceable. We will be happy to
28 * consider code for inclusion in the official distribution, but
29 * derived work must not be called official GROMACS. Details are found
30 * in the README & COPYING files - if they are missing, get the
31 * official version at http://www.gromacs.org.
33 * To help us fund GROMACS development, we humbly ask that you cite
34 * the research papers on the package. Check out http://www.gromacs.org.
44 #include "mtop_util.h"
47 #include "gmx_fatal.h"
49 static int gmx_mtop_maxresnr(const gmx_mtop_t *mtop, int maxres_renum)
56 for (mt = 0; mt < mtop->nmoltype; mt++)
58 atoms = &mtop->moltype[mt].atoms;
59 if (atoms->nres > maxres_renum)
61 for (r = 0; r < atoms->nres; r++)
63 if (atoms->resinfo[r].nr > maxresnr)
65 maxresnr = atoms->resinfo[r].nr;
74 void gmx_mtop_finalize(gmx_mtop_t *mtop)
78 mtop->maxres_renum = 1;
80 env = getenv("GMX_MAXRESRENUM");
83 sscanf(env, "%d", &mtop->maxres_renum);
85 if (mtop->maxres_renum == -1)
87 /* -1 signals renumber residues in all molecules */
88 mtop->maxres_renum = INT_MAX;
91 mtop->maxresnr = gmx_mtop_maxresnr(mtop, mtop->maxres_renum);
94 void gmx_mtop_count_atomtypes(const gmx_mtop_t *mtop, int state, int typecount[])
99 for (i = 0; i < mtop->ffparams.atnr; ++i)
103 for (mb = 0; mb < mtop->nmolblock; ++mb)
105 nmol = mtop->molblock[mb].nmol;
106 atoms = &mtop->moltype[mtop->molblock[mb].type].atoms;
107 for (i = 0; i < atoms->nr; ++i)
111 tpi = atoms->atom[i].type;
115 tpi = atoms->atom[i].typeB;
117 typecount[tpi] += nmol;
122 int ncg_mtop(const gmx_mtop_t *mtop)
128 for (mb = 0; mb < mtop->nmolblock; mb++)
131 mtop->molblock[mb].nmol*
132 mtop->moltype[mtop->molblock[mb].type].cgs.nr;
138 void gmx_mtop_remove_chargegroups(gmx_mtop_t *mtop)
144 for (mt = 0; mt < mtop->nmoltype; mt++)
146 cgs = &mtop->moltype[mt].cgs;
147 if (cgs->nr < mtop->moltype[mt].atoms.nr)
149 cgs->nr = mtop->moltype[mt].atoms.nr;
150 srenew(cgs->index, cgs->nr+1);
151 for (i = 0; i < cgs->nr+1; i++)
167 typedef struct gmx_mtop_atomlookup
169 const gmx_mtop_t *mtop;
173 } t_gmx_mtop_atomlookup;
176 gmx_mtop_atomlookup_t
177 gmx_mtop_atomlookup_init(const gmx_mtop_t *mtop)
179 t_gmx_mtop_atomlookup *alook;
181 int a_start, a_end, na, na_start = -1;
186 alook->nmb = mtop->nmolblock;
188 snew(alook->mba, alook->nmb);
191 for (mb = 0; mb < mtop->nmolblock; mb++)
193 na = mtop->molblock[mb].nmol*mtop->molblock[mb].natoms_mol;
194 a_end = a_start + na;
196 alook->mba[mb].a_start = a_start;
197 alook->mba[mb].a_end = a_end;
198 alook->mba[mb].na_mol = mtop->molblock[mb].natoms_mol;
200 /* We start the binary search with the largest block */
201 if (mb == 0 || na > na_start)
203 alook->mb_start = mb;
213 gmx_mtop_atomlookup_t
214 gmx_mtop_atomlookup_settle_init(const gmx_mtop_t *mtop)
216 t_gmx_mtop_atomlookup *alook;
218 int na, na_start = -1;
220 alook = gmx_mtop_atomlookup_init(mtop);
222 /* Check if the starting molblock has settle */
223 if (mtop->moltype[mtop->molblock[alook->mb_start].type].ilist[F_SETTLE].nr == 0)
225 /* Search the largest molblock with settle */
226 alook->mb_start = -1;
227 for (mb = 0; mb < mtop->nmolblock; mb++)
229 if (mtop->moltype[mtop->molblock[mb].type].ilist[F_SETTLE].nr > 0)
231 na = alook->mba[mb].a_end - alook->mba[mb].a_start;
232 if (alook->mb_start == -1 || na > na_start)
234 alook->mb_start = mb;
240 if (alook->mb_start == -1)
242 gmx_incons("gmx_mtop_atomlookup_settle_init called without settles");
250 gmx_mtop_atomlookup_destroy(gmx_mtop_atomlookup_t alook)
256 void gmx_mtop_atomnr_to_atom(const gmx_mtop_atomlookup_t alook,
261 int a_start, atnr_mol;
264 if (atnr_global < 0 || atnr_global >= mtop->natoms)
266 gmx_fatal(FARGS, "gmx_mtop_atomnr_to_moltype was called with atnr_global=%d which is not in the atom range of this system (%d-%d)",
267 atnr_global, 0, mtop->natoms-1);
273 mb = alook->mb_start;
277 a_start = alook->mba[mb].a_start;
278 if (atnr_global < a_start)
282 else if (atnr_global >= alook->mba[mb].a_end)
290 mb = ((mb0 + mb1 + 1)>>1);
293 atnr_mol = (atnr_global - a_start) % alook->mba[mb].na_mol;
295 *atom = &alook->mtop->moltype[alook->mtop->molblock[mb].type].atoms.atom[atnr_mol];
298 void gmx_mtop_atomnr_to_ilist(const gmx_mtop_atomlookup_t alook,
300 t_ilist **ilist_mol, int *atnr_offset)
303 int a_start, atnr_local;
306 if (atnr_global < 0 || atnr_global >= mtop->natoms)
308 gmx_fatal(FARGS, "gmx_mtop_atomnr_to_moltype was called with atnr_global=%d which is not in the atom range of this system (%d-%d)",
309 atnr_global, 0, mtop->natoms-1);
315 mb = alook->mb_start;
319 a_start = alook->mba[mb].a_start;
320 if (atnr_global < a_start)
324 else if (atnr_global >= alook->mba[mb].a_end)
332 mb = ((mb0 + mb1 + 1)>>1);
335 *ilist_mol = alook->mtop->moltype[alook->mtop->molblock[mb].type].ilist;
337 atnr_local = (atnr_global - a_start) % alook->mba[mb].na_mol;
339 *atnr_offset = atnr_global - atnr_local;
342 void gmx_mtop_atomnr_to_molblock_ind(const gmx_mtop_atomlookup_t alook,
344 int *molb, int *molnr, int *atnr_mol)
350 if (atnr_global < 0 || atnr_global >= mtop->natoms)
352 gmx_fatal(FARGS, "gmx_mtop_atomnr_to_moltype was called with atnr_global=%d which is not in the atom range of this system (%d-%d)",
353 atnr_global, 0, mtop->natoms-1);
359 mb = alook->mb_start;
363 a_start = alook->mba[mb].a_start;
364 if (atnr_global < a_start)
368 else if (atnr_global >= alook->mba[mb].a_end)
376 mb = ((mb0 + mb1 + 1)>>1);
380 *molnr = (atnr_global - a_start) / alook->mba[mb].na_mol;
381 *atnr_mol = atnr_global - a_start - (*molnr)*alook->mba[mb].na_mol;
384 void gmx_mtop_atominfo_global(const gmx_mtop_t *mtop, int atnr_global,
385 char **atomname, int *resnr, char **resname)
387 int mb, a_start, a_end, maxresnr, at_loc;
388 gmx_molblock_t *molb;
389 t_atoms *atoms = NULL;
391 if (atnr_global < 0 || atnr_global >= mtop->natoms)
393 gmx_fatal(FARGS, "gmx_mtop_atominfo_global was called with atnr_global=%d which is not in the atom range of this system (%d-%d)",
394 atnr_global, 0, mtop->natoms-1);
399 maxresnr = mtop->maxresnr;
404 if (atoms->nres <= mtop->maxres_renum)
406 /* Single residue molecule, keep counting */
407 maxresnr += mtop->molblock[mb].nmol*atoms->nres;
411 atoms = &mtop->moltype[mtop->molblock[mb].type].atoms;
413 a_end = a_start + mtop->molblock[mb].nmol*atoms->nr;
415 while (atnr_global >= a_end);
417 at_loc = (atnr_global - a_start) % atoms->nr;
418 *atomname = *(atoms->atomname[at_loc]);
419 if (atoms->nres > mtop->maxres_renum)
421 *resnr = atoms->resinfo[atoms->atom[at_loc].resind].nr;
425 /* Single residue molecule, keep counting */
426 *resnr = maxresnr + 1 + (atnr_global - a_start)/atoms->nr*atoms->nres + atoms->atom[at_loc].resind;
428 *resname = *(atoms->resinfo[atoms->atom[at_loc].resind].name);
431 typedef struct gmx_mtop_atomloop_all
433 const gmx_mtop_t *mtop;
440 } t_gmx_mtop_atomloop_all;
442 gmx_mtop_atomloop_all_t
443 gmx_mtop_atomloop_all_init(const gmx_mtop_t *mtop)
445 struct gmx_mtop_atomloop_all *aloop;
452 &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms;
454 aloop->maxresnr = mtop->maxresnr;
455 aloop->at_local = -1;
456 aloop->at_global = -1;
461 static void gmx_mtop_atomloop_all_destroy(gmx_mtop_atomloop_all_t aloop)
466 gmx_bool gmx_mtop_atomloop_all_next(gmx_mtop_atomloop_all_t aloop,
467 int *at_global, t_atom **atom)
471 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
477 if (aloop->at_local >= aloop->atoms->nr)
479 if (aloop->atoms->nres <= aloop->mtop->maxres_renum)
481 /* Single residue molecule, increase the count with one */
482 aloop->maxresnr += aloop->atoms->nres;
486 if (aloop->mol >= aloop->mtop->molblock[aloop->mblock].nmol)
489 if (aloop->mblock >= aloop->mtop->nmolblock)
491 gmx_mtop_atomloop_all_destroy(aloop);
494 aloop->atoms = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type].atoms;
499 *at_global = aloop->at_global;
500 *atom = &aloop->atoms->atom[aloop->at_local];
505 void gmx_mtop_atomloop_all_names(gmx_mtop_atomloop_all_t aloop,
506 char **atomname, int *resnr, char **resname)
510 *atomname = *(aloop->atoms->atomname[aloop->at_local]);
511 resind_mol = aloop->atoms->atom[aloop->at_local].resind;
512 *resnr = aloop->atoms->resinfo[resind_mol].nr;
513 if (aloop->atoms->nres <= aloop->mtop->maxres_renum)
515 *resnr = aloop->maxresnr + 1 + resind_mol;
517 *resname = *(aloop->atoms->resinfo[resind_mol].name);
520 void gmx_mtop_atomloop_all_moltype(gmx_mtop_atomloop_all_t aloop,
521 gmx_moltype_t **moltype, int *at_mol)
523 *moltype = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type];
524 *at_mol = aloop->at_local;
527 typedef struct gmx_mtop_atomloop_block
529 const gmx_mtop_t *mtop;
533 } t_gmx_mtop_atomloop_block;
535 gmx_mtop_atomloop_block_t
536 gmx_mtop_atomloop_block_init(const gmx_mtop_t *mtop)
538 struct gmx_mtop_atomloop_block *aloop;
544 aloop->atoms = &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms;
545 aloop->at_local = -1;
550 static void gmx_mtop_atomloop_block_destroy(gmx_mtop_atomloop_block_t aloop)
555 gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop,
556 t_atom **atom, int *nmol)
560 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
565 if (aloop->at_local >= aloop->atoms->nr)
568 if (aloop->mblock >= aloop->mtop->nmolblock)
570 gmx_mtop_atomloop_block_destroy(aloop);
573 aloop->atoms = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type].atoms;
577 *atom = &aloop->atoms->atom[aloop->at_local];
578 *nmol = aloop->mtop->molblock[aloop->mblock].nmol;
583 typedef struct gmx_mtop_ilistloop
585 const gmx_mtop_t *mtop;
590 gmx_mtop_ilistloop_init(const gmx_mtop_t *mtop)
592 struct gmx_mtop_ilistloop *iloop;
602 static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop)
607 gmx_bool gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop,
608 t_ilist **ilist_mol, int *nmol)
612 gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init");
616 if (iloop->mblock == iloop->mtop->nmolblock)
618 gmx_mtop_ilistloop_destroy(iloop);
623 iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
625 *nmol = iloop->mtop->molblock[iloop->mblock].nmol;
629 typedef struct gmx_mtop_ilistloop_all
631 const gmx_mtop_t *mtop;
635 } t_gmx_mtop_ilist_all;
637 gmx_mtop_ilistloop_all_t
638 gmx_mtop_ilistloop_all_init(const gmx_mtop_t *mtop)
640 struct gmx_mtop_ilistloop_all *iloop;
652 static void gmx_mtop_ilistloop_all_destroy(gmx_mtop_ilistloop_all_t iloop)
657 gmx_bool gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop,
658 t_ilist **ilist_mol, int *atnr_offset)
660 gmx_molblock_t *molb;
664 gmx_incons("gmx_mtop_ilistloop_all_next called without calling gmx_mtop_ilistloop_all_init");
669 iloop->a_offset += iloop->mtop->molblock[iloop->mblock].natoms_mol;
674 if (iloop->mol >= iloop->mtop->molblock[iloop->mblock].nmol)
678 if (iloop->mblock == iloop->mtop->nmolblock)
680 gmx_mtop_ilistloop_all_destroy(iloop);
686 iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
688 *atnr_offset = iloop->a_offset;
693 int gmx_mtop_ftype_count(const gmx_mtop_t *mtop, int ftype)
695 gmx_mtop_ilistloop_t iloop;
701 iloop = gmx_mtop_ilistloop_init(mtop);
702 while (gmx_mtop_ilistloop_next(iloop, &il, &nmol))
704 n += nmol*il[ftype].nr/(1+NRAL(ftype));
710 t_block gmx_mtop_global_cgs(const gmx_mtop_t *mtop)
712 t_block cgs_gl, *cgs_mol;
714 gmx_molblock_t *molb;
717 /* In most cases this is too much, but we realloc at the end */
718 snew(cgs_gl.index, mtop->natoms+1);
722 for (mb = 0; mb < mtop->nmolblock; mb++)
724 molb = &mtop->molblock[mb];
725 cgs_mol = &mtop->moltype[molb->type].cgs;
726 for (mol = 0; mol < molb->nmol; mol++)
728 for (cg = 0; cg < cgs_mol->nr; cg++)
730 cgs_gl.index[cgs_gl.nr+1] =
731 cgs_gl.index[cgs_gl.nr] +
732 cgs_mol->index[cg+1] - cgs_mol->index[cg];
737 cgs_gl.nalloc_index = cgs_gl.nr + 1;
738 srenew(cgs_gl.index, cgs_gl.nalloc_index);
743 static void atomcat(t_atoms *dest, t_atoms *src, int copies,
744 int maxres_renum, int *maxresnr)
748 int destnr = dest->nr;
752 size = destnr+copies*srcnr;
753 srenew(dest->atom, size);
754 srenew(dest->atomname, size);
755 srenew(dest->atomtype, size);
756 srenew(dest->atomtypeB, size);
760 size = dest->nres+copies*src->nres;
761 srenew(dest->resinfo, size);
764 /* residue information */
765 for (l = dest->nres, j = 0; (j < copies); j++, l += src->nres)
767 memcpy((char *) &(dest->resinfo[l]), (char *) &(src->resinfo[0]),
768 (size_t)(src->nres*sizeof(src->resinfo[0])));
771 for (l = destnr, j = 0; (j < copies); j++, l += srcnr)
773 memcpy((char *) &(dest->atomname[l]), (char *) &(src->atomname[0]),
774 (size_t)(srcnr*sizeof(src->atomname[0])));
775 memcpy((char *) &(dest->atomtype[l]), (char *) &(src->atomtype[0]),
776 (size_t)(srcnr*sizeof(src->atomtype[0])));
777 memcpy((char *) &(dest->atomtypeB[l]), (char *) &(src->atomtypeB[0]),
778 (size_t)(srcnr*sizeof(src->atomtypeB[0])));
779 memcpy((char *) &(dest->atom[l]), (char *) &(src->atom[0]),
780 (size_t)(srcnr*sizeof(src->atom[0])));
783 /* Increment residue indices */
784 for (l = destnr, j = 0; (j < copies); j++)
786 for (i = 0; (i < srcnr); i++, l++)
788 dest->atom[l].resind = dest->nres+j*src->nres+src->atom[i].resind;
792 if (src->nres <= maxres_renum)
794 /* Single residue molecule, continue counting residues */
795 for (j = 0; (j < copies); j++)
797 for (l = 0; l < src->nres; l++)
800 dest->resinfo[dest->nres+j*src->nres+l].nr = *maxresnr;
805 dest->nres += copies*src->nres;
806 dest->nr += copies*src->nr;
809 t_atoms gmx_mtop_global_atoms(const gmx_mtop_t *mtop)
813 gmx_molblock_t *molb;
815 init_t_atoms(&atoms, 0, FALSE);
817 maxresnr = mtop->maxresnr;
818 for (mb = 0; mb < mtop->nmolblock; mb++)
820 molb = &mtop->molblock[mb];
821 atomcat(&atoms, &mtop->moltype[molb->type].atoms, molb->nmol,
822 mtop->maxres_renum, &maxresnr);
828 void gmx_mtop_make_atomic_charge_groups(gmx_mtop_t *mtop,
829 gmx_bool bKeepSingleMolCG)
834 for (mb = 0; mb < mtop->nmolblock; mb++)
836 cgs_mol = &mtop->moltype[mtop->molblock[mb].type].cgs;
837 if (!(bKeepSingleMolCG && cgs_mol->nr == 1))
839 cgs_mol->nr = mtop->molblock[mb].natoms_mol;
840 cgs_mol->nalloc_index = cgs_mol->nr + 1;
841 srenew(cgs_mol->index, cgs_mol->nalloc_index);
842 for (cg = 0; cg < cgs_mol->nr+1; cg++)
844 cgs_mol->index[cg] = cg;
851 * The cat routines below are old code from src/kernel/topcat.c
854 static void blockcat(t_block *dest, t_block *src, int copies)
856 int i, j, l, nra, size;
860 size = (dest->nr+copies*src->nr+1);
861 srenew(dest->index, size);
864 nra = dest->index[dest->nr];
865 for (l = dest->nr, j = 0; (j < copies); j++)
867 for (i = 0; (i < src->nr); i++)
869 dest->index[l++] = nra + src->index[i];
871 nra += src->index[src->nr];
873 dest->nr += copies*src->nr;
874 dest->index[dest->nr] = nra;
877 static void blockacat(t_blocka *dest, t_blocka *src, int copies,
881 int destnr = dest->nr;
882 int destnra = dest->nra;
886 size = (dest->nr+copies*src->nr+1);
887 srenew(dest->index, size);
891 size = (dest->nra+copies*src->nra);
892 srenew(dest->a, size);
895 for (l = destnr, j = 0; (j < copies); j++)
897 for (i = 0; (i < src->nr); i++)
899 dest->index[l++] = dest->nra+src->index[i];
901 dest->nra += src->nra;
903 for (l = destnra, j = 0; (j < copies); j++)
905 for (i = 0; (i < src->nra); i++)
907 dest->a[l++] = dnum+src->a[i];
912 dest->index[dest->nr] = dest->nra;
915 static void ilistcat(int ftype, t_ilist *dest, t_ilist *src, int copies,
922 dest->nalloc = dest->nr + copies*src->nr;
923 srenew(dest->iatoms, dest->nalloc);
925 for (c = 0; c < copies; c++)
927 for (i = 0; i < src->nr; )
929 dest->iatoms[dest->nr++] = src->iatoms[i++];
930 for (a = 0; a < nral; a++)
932 dest->iatoms[dest->nr++] = dnum + src->iatoms[i++];
939 static void set_posres_params(t_idef *idef, gmx_molblock_t *molb,
940 int i0, int a_offset)
946 il = &idef->il[F_POSRES];
948 idef->iparams_posres_nalloc = i1;
949 srenew(idef->iparams_posres, idef->iparams_posres_nalloc);
950 for (i = i0; i < i1; i++)
952 ip = &idef->iparams_posres[i];
953 /* Copy the force constants */
954 *ip = idef->iparams[il->iatoms[i*2]];
955 a_molb = il->iatoms[i*2+1] - a_offset;
956 if (molb->nposres_xA == 0)
958 gmx_incons("Position restraint coordinates are missing");
960 ip->posres.pos0A[XX] = molb->posres_xA[a_molb][XX];
961 ip->posres.pos0A[YY] = molb->posres_xA[a_molb][YY];
962 ip->posres.pos0A[ZZ] = molb->posres_xA[a_molb][ZZ];
963 if (molb->nposres_xB > 0)
965 ip->posres.pos0B[XX] = molb->posres_xB[a_molb][XX];
966 ip->posres.pos0B[YY] = molb->posres_xB[a_molb][YY];
967 ip->posres.pos0B[ZZ] = molb->posres_xB[a_molb][ZZ];
971 ip->posres.pos0B[XX] = ip->posres.pos0A[XX];
972 ip->posres.pos0B[YY] = ip->posres.pos0A[YY];
973 ip->posres.pos0B[ZZ] = ip->posres.pos0A[ZZ];
975 /* Set the parameter index for idef->iparams_posre */
980 static void set_fbposres_params(t_idef *idef, gmx_molblock_t *molb,
981 int i0, int a_offset)
987 il = &idef->il[F_FBPOSRES];
989 idef->iparams_fbposres_nalloc = i1;
990 srenew(idef->iparams_fbposres, idef->iparams_fbposres_nalloc);
991 for (i = i0; i < i1; i++)
993 ip = &idef->iparams_fbposres[i];
994 /* Copy the force constants */
995 *ip = idef->iparams[il->iatoms[i*2]];
996 a_molb = il->iatoms[i*2+1] - a_offset;
997 if (molb->nposres_xA == 0)
999 gmx_incons("Position restraint coordinates are missing");
1001 /* Take flat-bottom posres reference from normal position restraints */
1002 ip->fbposres.pos0[XX] = molb->posres_xA[a_molb][XX];
1003 ip->fbposres.pos0[YY] = molb->posres_xA[a_molb][YY];
1004 ip->fbposres.pos0[ZZ] = molb->posres_xA[a_molb][ZZ];
1005 /* Note: no B-type for flat-bottom posres */
1007 /* Set the parameter index for idef->iparams_posre */
1008 il->iatoms[i*2] = i;
1012 static void gen_local_top(const gmx_mtop_t *mtop, const t_inputrec *ir,
1013 gmx_bool bMergeConstr,
1014 gmx_localtop_t *top)
1016 int mb, srcnr, destnr, ftype, ftype_dest, mt, natoms, mol, nposre_old, nfbposre_old;
1017 gmx_molblock_t *molb;
1018 gmx_moltype_t *molt;
1019 const gmx_ffparams_t *ffp;
1022 gmx_mtop_atomloop_all_t aloop;
1026 top->atomtypes = mtop->atomtypes;
1028 ffp = &mtop->ffparams;
1031 idef->ntypes = ffp->ntypes;
1032 idef->atnr = ffp->atnr;
1033 idef->functype = ffp->functype;
1034 idef->iparams = ffp->iparams;
1035 idef->iparams_posres = NULL;
1036 idef->iparams_posres_nalloc = 0;
1037 idef->iparams_fbposres = NULL;
1038 idef->iparams_fbposres_nalloc = 0;
1039 idef->fudgeQQ = ffp->fudgeQQ;
1040 idef->cmap_grid = ffp->cmap_grid;
1041 idef->ilsort = ilsortUNKNOWN;
1043 init_block(&top->cgs);
1044 init_blocka(&top->excls);
1045 for (ftype = 0; ftype < F_NRE; ftype++)
1047 idef->il[ftype].nr = 0;
1048 idef->il[ftype].nalloc = 0;
1049 idef->il[ftype].iatoms = NULL;
1053 for (mb = 0; mb < mtop->nmolblock; mb++)
1055 molb = &mtop->molblock[mb];
1056 molt = &mtop->moltype[molb->type];
1058 srcnr = molt->atoms.nr;
1061 blockcat(&top->cgs, &molt->cgs, molb->nmol);
1063 blockacat(&top->excls, &molt->excls, molb->nmol, destnr, srcnr);
1065 nposre_old = idef->il[F_POSRES].nr;
1066 nfbposre_old = idef->il[F_FBPOSRES].nr;
1067 for (ftype = 0; ftype < F_NRE; ftype++)
1070 ftype == F_CONSTR && molt->ilist[F_CONSTRNC].nr > 0)
1072 /* Merge all constrains into one ilist.
1073 * This simplifies the constraint code.
1075 for (mol = 0; mol < molb->nmol; mol++)
1077 ilistcat(ftype, &idef->il[F_CONSTR], &molt->ilist[F_CONSTR],
1078 1, destnr+mol*srcnr, srcnr);
1079 ilistcat(ftype, &idef->il[F_CONSTR], &molt->ilist[F_CONSTRNC],
1080 1, destnr+mol*srcnr, srcnr);
1083 else if (!(bMergeConstr && ftype == F_CONSTRNC))
1085 ilistcat(ftype, &idef->il[ftype], &molt->ilist[ftype],
1086 molb->nmol, destnr, srcnr);
1089 if (idef->il[F_POSRES].nr > nposre_old)
1091 /* Executing this line line stops gmxdump -sys working
1092 * correctly. I'm not aware there's an elegant fix. */
1093 set_posres_params(idef, molb, nposre_old/2, natoms);
1095 if (idef->il[F_FBPOSRES].nr > nfbposre_old)
1097 set_fbposres_params(idef, molb, nfbposre_old/2, natoms);
1100 natoms += molb->nmol*srcnr;
1105 top->idef.ilsort = ilsortUNKNOWN;
1109 if (ir->efep != efepNO && gmx_mtop_bondeds_free_energy(mtop))
1111 snew(qA, mtop->natoms);
1112 snew(qB, mtop->natoms);
1113 aloop = gmx_mtop_atomloop_all_init(mtop);
1114 while (gmx_mtop_atomloop_all_next(aloop, &ag, &atom))
1119 gmx_sort_ilist_fe(&top->idef, qA, qB);
1125 top->idef.ilsort = ilsortNO_FE;
1130 gmx_localtop_t *gmx_mtop_generate_local_top(const gmx_mtop_t *mtop,
1131 const t_inputrec *ir)
1133 gmx_localtop_t *top;
1137 gen_local_top(mtop, ir, TRUE, top);
1142 t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop)
1145 gmx_localtop_t ltop;
1148 gen_local_top(mtop, NULL, FALSE, <op);
1150 top.name = mtop->name;
1151 top.idef = ltop.idef;
1152 top.atomtypes = ltop.atomtypes;
1154 top.excls = ltop.excls;
1155 top.atoms = gmx_mtop_global_atoms(mtop);
1156 top.mols = mtop->mols;
1157 top.symtab = mtop->symtab;
1159 /* We only need to free the moltype and molblock data,
1160 * all other pointers have been copied to top.
1162 * Well, except for the group data, but we can't free those, because they
1163 * are used somewhere even after a call to this function.
1165 for (mt = 0; mt < mtop->nmoltype; mt++)
1167 done_moltype(&mtop->moltype[mt]);
1169 sfree(mtop->moltype);
1171 for (mb = 0; mb < mtop->nmolblock; mb++)
1173 done_molblock(&mtop->molblock[mb]);
1175 sfree(mtop->molblock);