2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2008,2009,2010,2012,2013,2014,2015, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 #include "mtop_util.h"
45 #include "gromacs/legacyheaders/types/enums.h"
46 #include "gromacs/legacyheaders/types/ifunc.h"
47 #include "gromacs/legacyheaders/types/inputrec.h"
48 #include "gromacs/legacyheaders/types/simple.h"
49 #include "gromacs/math/vectypes.h"
50 #include "gromacs/topology/atoms.h"
51 #include "gromacs/topology/block.h"
52 #include "gromacs/topology/idef.h"
53 #include "gromacs/topology/topology.h"
54 #include "gromacs/topology/topsort.h"
55 #include "gromacs/utility/fatalerror.h"
56 #include "gromacs/utility/real.h"
57 #include "gromacs/utility/smalloc.h"
59 static int gmx_mtop_maxresnr(const gmx_mtop_t *mtop, int maxres_renum)
66 for (mt = 0; mt < mtop->nmoltype; mt++)
68 atoms = &mtop->moltype[mt].atoms;
69 if (atoms->nres > maxres_renum)
71 for (r = 0; r < atoms->nres; r++)
73 if (atoms->resinfo[r].nr > maxresnr)
75 maxresnr = atoms->resinfo[r].nr;
84 void gmx_mtop_finalize(gmx_mtop_t *mtop)
88 mtop->maxres_renum = 1;
90 env = getenv("GMX_MAXRESRENUM");
93 sscanf(env, "%d", &mtop->maxres_renum);
95 if (mtop->maxres_renum == -1)
97 /* -1 signals renumber residues in all molecules */
98 mtop->maxres_renum = INT_MAX;
101 mtop->maxresnr = gmx_mtop_maxresnr(mtop, mtop->maxres_renum);
104 void gmx_mtop_count_atomtypes(const gmx_mtop_t *mtop, int state, int typecount[])
106 int i, mb, nmol, tpi;
109 for (i = 0; i < mtop->ffparams.atnr; ++i)
113 for (mb = 0; mb < mtop->nmolblock; ++mb)
115 nmol = mtop->molblock[mb].nmol;
116 atoms = &mtop->moltype[mtop->molblock[mb].type].atoms;
117 for (i = 0; i < atoms->nr; ++i)
121 tpi = atoms->atom[i].type;
125 tpi = atoms->atom[i].typeB;
127 typecount[tpi] += nmol;
132 int ncg_mtop(const gmx_mtop_t *mtop)
138 for (mb = 0; mb < mtop->nmolblock; mb++)
141 mtop->molblock[mb].nmol*
142 mtop->moltype[mtop->molblock[mb].type].cgs.nr;
148 void gmx_mtop_remove_chargegroups(gmx_mtop_t *mtop)
154 for (mt = 0; mt < mtop->nmoltype; mt++)
156 cgs = &mtop->moltype[mt].cgs;
157 if (cgs->nr < mtop->moltype[mt].atoms.nr)
159 cgs->nr = mtop->moltype[mt].atoms.nr;
160 srenew(cgs->index, cgs->nr+1);
161 for (i = 0; i < cgs->nr+1; i++)
177 typedef struct gmx_mtop_atomlookup
179 const gmx_mtop_t *mtop;
183 } t_gmx_mtop_atomlookup;
186 gmx_mtop_atomlookup_t
187 gmx_mtop_atomlookup_init(const gmx_mtop_t *mtop)
189 t_gmx_mtop_atomlookup *alook;
191 int a_start, a_end, na, na_start = -1;
196 alook->nmb = mtop->nmolblock;
198 snew(alook->mba, alook->nmb);
201 for (mb = 0; mb < mtop->nmolblock; mb++)
203 na = mtop->molblock[mb].nmol*mtop->molblock[mb].natoms_mol;
204 a_end = a_start + na;
206 alook->mba[mb].a_start = a_start;
207 alook->mba[mb].a_end = a_end;
208 alook->mba[mb].na_mol = mtop->molblock[mb].natoms_mol;
210 /* We start the binary search with the largest block */
211 if (mb == 0 || na > na_start)
213 alook->mb_start = mb;
223 gmx_mtop_atomlookup_t
224 gmx_mtop_atomlookup_settle_init(const gmx_mtop_t *mtop)
226 t_gmx_mtop_atomlookup *alook;
228 int na, na_start = -1;
230 alook = gmx_mtop_atomlookup_init(mtop);
232 /* Check if the starting molblock has settle */
233 if (mtop->moltype[mtop->molblock[alook->mb_start].type].ilist[F_SETTLE].nr == 0)
235 /* Search the largest molblock with settle */
236 alook->mb_start = -1;
237 for (mb = 0; mb < mtop->nmolblock; mb++)
239 if (mtop->moltype[mtop->molblock[mb].type].ilist[F_SETTLE].nr > 0)
241 na = alook->mba[mb].a_end - alook->mba[mb].a_start;
242 if (alook->mb_start == -1 || na > na_start)
244 alook->mb_start = mb;
250 if (alook->mb_start == -1)
252 gmx_incons("gmx_mtop_atomlookup_settle_init called without settles");
260 gmx_mtop_atomlookup_destroy(gmx_mtop_atomlookup_t alook)
266 void gmx_mtop_atomnr_to_atom(const gmx_mtop_atomlookup_t alook,
271 int a_start, atnr_mol;
274 if (atnr_global < 0 || atnr_global >= mtop->natoms)
276 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)",
277 atnr_global, 0, mtop->natoms-1);
283 mb = alook->mb_start;
287 a_start = alook->mba[mb].a_start;
288 if (atnr_global < a_start)
292 else if (atnr_global >= alook->mba[mb].a_end)
300 mb = ((mb0 + mb1 + 1)>>1);
303 atnr_mol = (atnr_global - a_start) % alook->mba[mb].na_mol;
305 *atom = &alook->mtop->moltype[alook->mtop->molblock[mb].type].atoms.atom[atnr_mol];
308 void gmx_mtop_atomnr_to_ilist(const gmx_mtop_atomlookup_t alook,
310 t_ilist **ilist_mol, int *atnr_offset)
313 int a_start, atnr_local;
316 if (atnr_global < 0 || atnr_global >= mtop->natoms)
318 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)",
319 atnr_global, 0, mtop->natoms-1);
325 mb = alook->mb_start;
329 a_start = alook->mba[mb].a_start;
330 if (atnr_global < a_start)
334 else if (atnr_global >= alook->mba[mb].a_end)
342 mb = ((mb0 + mb1 + 1)>>1);
345 *ilist_mol = alook->mtop->moltype[alook->mtop->molblock[mb].type].ilist;
347 atnr_local = (atnr_global - a_start) % alook->mba[mb].na_mol;
349 *atnr_offset = atnr_global - atnr_local;
352 void gmx_mtop_atomnr_to_molblock_ind(const gmx_mtop_atomlookup_t alook,
354 int *molb, int *molnr, int *atnr_mol)
360 if (atnr_global < 0 || atnr_global >= mtop->natoms)
362 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)",
363 atnr_global, 0, mtop->natoms-1);
369 mb = alook->mb_start;
373 a_start = alook->mba[mb].a_start;
374 if (atnr_global < a_start)
378 else if (atnr_global >= alook->mba[mb].a_end)
386 mb = ((mb0 + mb1 + 1)>>1);
390 *molnr = (atnr_global - a_start) / alook->mba[mb].na_mol;
391 *atnr_mol = atnr_global - a_start - (*molnr)*alook->mba[mb].na_mol;
394 void gmx_mtop_atominfo_global(const gmx_mtop_t *mtop, int atnr_global,
395 char **atomname, int *resnr, char **resname)
397 int mb, a_start, a_end, maxresnr, at_loc;
398 gmx_molblock_t *molb;
399 t_atoms *atoms = NULL;
401 if (atnr_global < 0 || atnr_global >= mtop->natoms)
403 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)",
404 atnr_global, 0, mtop->natoms-1);
409 maxresnr = mtop->maxresnr;
414 /* cppcheck-suppress nullPointer #6330*/
415 if (atoms->nres <= mtop->maxres_renum)
417 /* Single residue molecule, keep counting */
418 /* cppcheck-suppress nullPointer #6330*/
419 maxresnr += mtop->molblock[mb].nmol*atoms->nres;
423 atoms = &mtop->moltype[mtop->molblock[mb].type].atoms;
425 a_end = a_start + mtop->molblock[mb].nmol*atoms->nr;
427 while (atnr_global >= a_end);
429 at_loc = (atnr_global - a_start) % atoms->nr;
430 *atomname = *(atoms->atomname[at_loc]);
431 if (atoms->nres > mtop->maxres_renum)
433 *resnr = atoms->resinfo[atoms->atom[at_loc].resind].nr;
437 /* Single residue molecule, keep counting */
438 *resnr = maxresnr + 1 + (atnr_global - a_start)/atoms->nr*atoms->nres + atoms->atom[at_loc].resind;
440 *resname = *(atoms->resinfo[atoms->atom[at_loc].resind].name);
443 typedef struct gmx_mtop_atomloop_all
445 const gmx_mtop_t *mtop;
452 } t_gmx_mtop_atomloop_all;
454 gmx_mtop_atomloop_all_t
455 gmx_mtop_atomloop_all_init(const gmx_mtop_t *mtop)
457 struct gmx_mtop_atomloop_all *aloop;
464 &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms;
466 aloop->maxresnr = mtop->maxresnr;
467 aloop->at_local = -1;
468 aloop->at_global = -1;
473 static void gmx_mtop_atomloop_all_destroy(gmx_mtop_atomloop_all_t aloop)
478 gmx_bool gmx_mtop_atomloop_all_next(gmx_mtop_atomloop_all_t aloop,
479 int *at_global, t_atom **atom)
483 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
489 if (aloop->at_local >= aloop->atoms->nr)
491 if (aloop->atoms->nres <= aloop->mtop->maxres_renum)
493 /* Single residue molecule, increase the count with one */
494 aloop->maxresnr += aloop->atoms->nres;
498 if (aloop->mol >= aloop->mtop->molblock[aloop->mblock].nmol)
501 if (aloop->mblock >= aloop->mtop->nmolblock)
503 gmx_mtop_atomloop_all_destroy(aloop);
506 aloop->atoms = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type].atoms;
511 *at_global = aloop->at_global;
512 *atom = &aloop->atoms->atom[aloop->at_local];
517 void gmx_mtop_atomloop_all_names(gmx_mtop_atomloop_all_t aloop,
518 char **atomname, int *resnr, char **resname)
522 *atomname = *(aloop->atoms->atomname[aloop->at_local]);
523 resind_mol = aloop->atoms->atom[aloop->at_local].resind;
524 *resnr = aloop->atoms->resinfo[resind_mol].nr;
525 if (aloop->atoms->nres <= aloop->mtop->maxres_renum)
527 *resnr = aloop->maxresnr + 1 + resind_mol;
529 *resname = *(aloop->atoms->resinfo[resind_mol].name);
532 void gmx_mtop_atomloop_all_moltype(gmx_mtop_atomloop_all_t aloop,
533 gmx_moltype_t **moltype, int *at_mol)
535 *moltype = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type];
536 *at_mol = aloop->at_local;
539 typedef struct gmx_mtop_atomloop_block
541 const gmx_mtop_t *mtop;
545 } t_gmx_mtop_atomloop_block;
547 gmx_mtop_atomloop_block_t
548 gmx_mtop_atomloop_block_init(const gmx_mtop_t *mtop)
550 struct gmx_mtop_atomloop_block *aloop;
556 aloop->atoms = &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms;
557 aloop->at_local = -1;
562 static void gmx_mtop_atomloop_block_destroy(gmx_mtop_atomloop_block_t aloop)
567 gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop,
568 t_atom **atom, int *nmol)
572 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
577 if (aloop->at_local >= aloop->atoms->nr)
580 if (aloop->mblock >= aloop->mtop->nmolblock)
582 gmx_mtop_atomloop_block_destroy(aloop);
585 aloop->atoms = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type].atoms;
589 *atom = &aloop->atoms->atom[aloop->at_local];
590 *nmol = aloop->mtop->molblock[aloop->mblock].nmol;
595 typedef struct gmx_mtop_ilistloop
597 const gmx_mtop_t *mtop;
602 gmx_mtop_ilistloop_init(const gmx_mtop_t *mtop)
604 struct gmx_mtop_ilistloop *iloop;
614 static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop)
619 gmx_bool gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop,
620 t_ilist **ilist_mol, int *nmol)
624 gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init");
628 if (iloop->mblock >= iloop->mtop->nmolblock)
630 if (iloop->mblock == iloop->mtop->nmolblock &&
631 iloop->mtop->bIntermolecularInteractions)
633 *ilist_mol = iloop->mtop->intermolecular_ilist;
638 gmx_mtop_ilistloop_destroy(iloop);
643 iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
645 *nmol = iloop->mtop->molblock[iloop->mblock].nmol;
649 typedef struct gmx_mtop_ilistloop_all
651 const gmx_mtop_t *mtop;
655 } t_gmx_mtop_ilist_all;
657 gmx_mtop_ilistloop_all_t
658 gmx_mtop_ilistloop_all_init(const gmx_mtop_t *mtop)
660 struct gmx_mtop_ilistloop_all *iloop;
672 static void gmx_mtop_ilistloop_all_destroy(gmx_mtop_ilistloop_all_t iloop)
677 gmx_bool gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop,
678 t_ilist **ilist_mol, int *atnr_offset)
680 gmx_molblock_t *molb;
684 gmx_incons("gmx_mtop_ilistloop_all_next called without calling gmx_mtop_ilistloop_all_init");
689 iloop->a_offset += iloop->mtop->molblock[iloop->mblock].natoms_mol;
694 /* Inter-molecular interactions, if present, are indexed with
695 * iloop->mblock == iloop->mtop->nmolblock, thus we should separately
696 * check for this value in this conditional.
698 if (iloop->mblock == iloop->mtop->nmolblock ||
699 iloop->mol >= iloop->mtop->molblock[iloop->mblock].nmol)
703 if (iloop->mblock >= iloop->mtop->nmolblock)
705 if (iloop->mblock == iloop->mtop->nmolblock &&
706 iloop->mtop->bIntermolecularInteractions)
708 *ilist_mol = iloop->mtop->intermolecular_ilist;
713 gmx_mtop_ilistloop_all_destroy(iloop);
719 iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
721 *atnr_offset = iloop->a_offset;
726 int gmx_mtop_ftype_count(const gmx_mtop_t *mtop, int ftype)
728 gmx_mtop_ilistloop_t iloop;
734 iloop = gmx_mtop_ilistloop_init(mtop);
735 while (gmx_mtop_ilistloop_next(iloop, &il, &nmol))
737 n += nmol*il[ftype].nr/(1+NRAL(ftype));
740 if (mtop->bIntermolecularInteractions)
742 n += mtop->intermolecular_ilist[ftype].nr/(1+NRAL(ftype));
748 t_block gmx_mtop_global_cgs(const gmx_mtop_t *mtop)
750 t_block cgs_gl, *cgs_mol;
752 gmx_molblock_t *molb;
755 /* In most cases this is too much, but we realloc at the end */
756 snew(cgs_gl.index, mtop->natoms+1);
760 for (mb = 0; mb < mtop->nmolblock; mb++)
762 molb = &mtop->molblock[mb];
763 cgs_mol = &mtop->moltype[molb->type].cgs;
764 for (mol = 0; mol < molb->nmol; mol++)
766 for (cg = 0; cg < cgs_mol->nr; cg++)
768 cgs_gl.index[cgs_gl.nr+1] =
769 cgs_gl.index[cgs_gl.nr] +
770 cgs_mol->index[cg+1] - cgs_mol->index[cg];
775 cgs_gl.nalloc_index = cgs_gl.nr + 1;
776 srenew(cgs_gl.index, cgs_gl.nalloc_index);
781 static void atomcat(t_atoms *dest, t_atoms *src, int copies,
782 int maxres_renum, int *maxresnr)
786 int destnr = dest->nr;
790 size = destnr+copies*srcnr;
791 srenew(dest->atom, size);
792 srenew(dest->atomname, size);
793 srenew(dest->atomtype, size);
794 srenew(dest->atomtypeB, size);
798 size = dest->nres+copies*src->nres;
799 srenew(dest->resinfo, size);
802 /* residue information */
803 for (l = dest->nres, j = 0; (j < copies); j++, l += src->nres)
805 memcpy((char *) &(dest->resinfo[l]), (char *) &(src->resinfo[0]),
806 (size_t)(src->nres*sizeof(src->resinfo[0])));
809 for (l = destnr, j = 0; (j < copies); j++, l += srcnr)
811 memcpy((char *) &(dest->atomname[l]), (char *) &(src->atomname[0]),
812 (size_t)(srcnr*sizeof(src->atomname[0])));
813 memcpy((char *) &(dest->atomtype[l]), (char *) &(src->atomtype[0]),
814 (size_t)(srcnr*sizeof(src->atomtype[0])));
815 memcpy((char *) &(dest->atomtypeB[l]), (char *) &(src->atomtypeB[0]),
816 (size_t)(srcnr*sizeof(src->atomtypeB[0])));
817 memcpy((char *) &(dest->atom[l]), (char *) &(src->atom[0]),
818 (size_t)(srcnr*sizeof(src->atom[0])));
821 /* Increment residue indices */
822 for (l = destnr, j = 0; (j < copies); j++)
824 for (i = 0; (i < srcnr); i++, l++)
826 dest->atom[l].resind = dest->nres+j*src->nres+src->atom[i].resind;
830 if (src->nres <= maxres_renum)
832 /* Single residue molecule, continue counting residues */
833 for (j = 0; (j < copies); j++)
835 for (l = 0; l < src->nres; l++)
838 dest->resinfo[dest->nres+j*src->nres+l].nr = *maxresnr;
843 dest->nres += copies*src->nres;
844 dest->nr += copies*src->nr;
847 t_atoms gmx_mtop_global_atoms(const gmx_mtop_t *mtop)
851 gmx_molblock_t *molb;
853 init_t_atoms(&atoms, 0, FALSE);
855 maxresnr = mtop->maxresnr;
856 for (mb = 0; mb < mtop->nmolblock; mb++)
858 molb = &mtop->molblock[mb];
859 atomcat(&atoms, &mtop->moltype[molb->type].atoms, molb->nmol,
860 mtop->maxres_renum, &maxresnr);
866 void gmx_mtop_make_atomic_charge_groups(gmx_mtop_t *mtop,
867 gmx_bool bKeepSingleMolCG)
872 for (mb = 0; mb < mtop->nmolblock; mb++)
874 cgs_mol = &mtop->moltype[mtop->molblock[mb].type].cgs;
875 if (!(bKeepSingleMolCG && cgs_mol->nr == 1))
877 cgs_mol->nr = mtop->molblock[mb].natoms_mol;
878 cgs_mol->nalloc_index = cgs_mol->nr + 1;
879 srenew(cgs_mol->index, cgs_mol->nalloc_index);
880 for (cg = 0; cg < cgs_mol->nr+1; cg++)
882 cgs_mol->index[cg] = cg;
889 * The cat routines below are old code from src/kernel/topcat.c
892 static void blockcat(t_block *dest, t_block *src, int copies)
894 int i, j, l, nra, size;
898 size = (dest->nr+copies*src->nr+1);
899 srenew(dest->index, size);
902 nra = dest->index[dest->nr];
903 for (l = dest->nr, j = 0; (j < copies); j++)
905 for (i = 0; (i < src->nr); i++)
907 dest->index[l++] = nra + src->index[i];
909 nra += src->index[src->nr];
911 dest->nr += copies*src->nr;
912 dest->index[dest->nr] = nra;
915 static void blockacat(t_blocka *dest, t_blocka *src, int copies,
919 int destnr = dest->nr;
920 int destnra = dest->nra;
924 size = (dest->nr+copies*src->nr+1);
925 srenew(dest->index, size);
929 size = (dest->nra+copies*src->nra);
930 srenew(dest->a, size);
933 for (l = destnr, j = 0; (j < copies); j++)
935 for (i = 0; (i < src->nr); i++)
937 dest->index[l++] = dest->nra+src->index[i];
939 dest->nra += src->nra;
941 for (l = destnra, j = 0; (j < copies); j++)
943 for (i = 0; (i < src->nra); i++)
945 dest->a[l++] = dnum+src->a[i];
950 dest->index[dest->nr] = dest->nra;
953 static void ilistcat(int ftype, t_ilist *dest, t_ilist *src, int copies,
960 dest->nalloc = dest->nr + copies*src->nr;
961 srenew(dest->iatoms, dest->nalloc);
963 for (c = 0; c < copies; c++)
965 for (i = 0; i < src->nr; )
967 dest->iatoms[dest->nr++] = src->iatoms[i++];
968 for (a = 0; a < nral; a++)
970 dest->iatoms[dest->nr++] = dnum + src->iatoms[i++];
977 static void set_posres_params(t_idef *idef, gmx_molblock_t *molb,
978 int i0, int a_offset)
984 il = &idef->il[F_POSRES];
986 idef->iparams_posres_nalloc = i1;
987 srenew(idef->iparams_posres, idef->iparams_posres_nalloc);
988 for (i = i0; i < i1; i++)
990 ip = &idef->iparams_posres[i];
991 /* Copy the force constants */
992 *ip = idef->iparams[il->iatoms[i*2]];
993 a_molb = il->iatoms[i*2+1] - a_offset;
994 if (molb->nposres_xA == 0)
996 gmx_incons("Position restraint coordinates are missing");
998 ip->posres.pos0A[XX] = molb->posres_xA[a_molb][XX];
999 ip->posres.pos0A[YY] = molb->posres_xA[a_molb][YY];
1000 ip->posres.pos0A[ZZ] = molb->posres_xA[a_molb][ZZ];
1001 if (molb->nposres_xB > 0)
1003 ip->posres.pos0B[XX] = molb->posres_xB[a_molb][XX];
1004 ip->posres.pos0B[YY] = molb->posres_xB[a_molb][YY];
1005 ip->posres.pos0B[ZZ] = molb->posres_xB[a_molb][ZZ];
1009 ip->posres.pos0B[XX] = ip->posres.pos0A[XX];
1010 ip->posres.pos0B[YY] = ip->posres.pos0A[YY];
1011 ip->posres.pos0B[ZZ] = ip->posres.pos0A[ZZ];
1013 /* Set the parameter index for idef->iparams_posre */
1014 il->iatoms[i*2] = i;
1018 static void set_fbposres_params(t_idef *idef, gmx_molblock_t *molb,
1019 int i0, int a_offset)
1025 il = &idef->il[F_FBPOSRES];
1027 idef->iparams_fbposres_nalloc = i1;
1028 srenew(idef->iparams_fbposres, idef->iparams_fbposres_nalloc);
1029 for (i = i0; i < i1; i++)
1031 ip = &idef->iparams_fbposres[i];
1032 /* Copy the force constants */
1033 *ip = idef->iparams[il->iatoms[i*2]];
1034 a_molb = il->iatoms[i*2+1] - a_offset;
1035 if (molb->nposres_xA == 0)
1037 gmx_incons("Position restraint coordinates are missing");
1039 /* Take flat-bottom posres reference from normal position restraints */
1040 ip->fbposres.pos0[XX] = molb->posres_xA[a_molb][XX];
1041 ip->fbposres.pos0[YY] = molb->posres_xA[a_molb][YY];
1042 ip->fbposres.pos0[ZZ] = molb->posres_xA[a_molb][ZZ];
1043 /* Note: no B-type for flat-bottom posres */
1045 /* Set the parameter index for idef->iparams_posre */
1046 il->iatoms[i*2] = i;
1050 static void gen_local_top(const gmx_mtop_t *mtop, const t_inputrec *ir,
1051 gmx_bool bMergeConstr,
1052 gmx_localtop_t *top)
1054 int mb, srcnr, destnr, ftype, ftype_dest, mt, natoms, mol, nposre_old, nfbposre_old;
1055 gmx_molblock_t *molb;
1056 gmx_moltype_t *molt;
1057 const gmx_ffparams_t *ffp;
1060 gmx_mtop_atomloop_all_t aloop;
1064 top->atomtypes = mtop->atomtypes;
1066 ffp = &mtop->ffparams;
1069 idef->ntypes = ffp->ntypes;
1070 idef->atnr = ffp->atnr;
1071 idef->functype = ffp->functype;
1072 idef->iparams = ffp->iparams;
1073 idef->iparams_posres = NULL;
1074 idef->iparams_posres_nalloc = 0;
1075 idef->iparams_fbposres = NULL;
1076 idef->iparams_fbposres_nalloc = 0;
1077 idef->fudgeQQ = ffp->fudgeQQ;
1078 idef->cmap_grid = ffp->cmap_grid;
1079 idef->ilsort = ilsortUNKNOWN;
1081 init_block(&top->cgs);
1082 init_blocka(&top->excls);
1083 for (ftype = 0; ftype < F_NRE; ftype++)
1085 idef->il[ftype].nr = 0;
1086 idef->il[ftype].nalloc = 0;
1087 idef->il[ftype].iatoms = NULL;
1091 for (mb = 0; mb < mtop->nmolblock; mb++)
1093 molb = &mtop->molblock[mb];
1094 molt = &mtop->moltype[molb->type];
1096 srcnr = molt->atoms.nr;
1099 blockcat(&top->cgs, &molt->cgs, molb->nmol);
1101 blockacat(&top->excls, &molt->excls, molb->nmol, destnr, srcnr);
1103 nposre_old = idef->il[F_POSRES].nr;
1104 nfbposre_old = idef->il[F_FBPOSRES].nr;
1105 for (ftype = 0; ftype < F_NRE; ftype++)
1108 ftype == F_CONSTR && molt->ilist[F_CONSTRNC].nr > 0)
1110 /* Merge all constrains into one ilist.
1111 * This simplifies the constraint code.
1113 for (mol = 0; mol < molb->nmol; mol++)
1115 ilistcat(ftype, &idef->il[F_CONSTR], &molt->ilist[F_CONSTR],
1116 1, destnr+mol*srcnr, srcnr);
1117 ilistcat(ftype, &idef->il[F_CONSTR], &molt->ilist[F_CONSTRNC],
1118 1, destnr+mol*srcnr, srcnr);
1121 else if (!(bMergeConstr && ftype == F_CONSTRNC))
1123 ilistcat(ftype, &idef->il[ftype], &molt->ilist[ftype],
1124 molb->nmol, destnr, srcnr);
1127 if (idef->il[F_POSRES].nr > nposre_old)
1129 /* Executing this line line stops gmxdump -sys working
1130 * correctly. I'm not aware there's an elegant fix. */
1131 set_posres_params(idef, molb, nposre_old/2, natoms);
1133 if (idef->il[F_FBPOSRES].nr > nfbposre_old)
1135 set_fbposres_params(idef, molb, nfbposre_old/2, natoms);
1138 natoms += molb->nmol*srcnr;
1141 if (mtop->bIntermolecularInteractions)
1143 for (ftype = 0; ftype < F_NRE; ftype++)
1145 ilistcat(ftype, &idef->il[ftype], &mtop->intermolecular_ilist[ftype],
1146 1, 0, mtop->natoms);
1152 top->idef.ilsort = ilsortUNKNOWN;
1156 if (ir->efep != efepNO && gmx_mtop_bondeds_free_energy(mtop))
1158 snew(qA, mtop->natoms);
1159 snew(qB, mtop->natoms);
1160 aloop = gmx_mtop_atomloop_all_init(mtop);
1161 while (gmx_mtop_atomloop_all_next(aloop, &ag, &atom))
1166 gmx_sort_ilist_fe(&top->idef, qA, qB);
1172 top->idef.ilsort = ilsortNO_FE;
1177 gmx_localtop_t *gmx_mtop_generate_local_top(const gmx_mtop_t *mtop,
1178 const t_inputrec *ir)
1180 gmx_localtop_t *top;
1184 gen_local_top(mtop, ir, TRUE, top);
1189 t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop)
1192 gmx_localtop_t ltop;
1195 gen_local_top(mtop, NULL, FALSE, <op);
1197 top.name = mtop->name;
1198 top.idef = ltop.idef;
1199 top.atomtypes = ltop.atomtypes;
1201 top.excls = ltop.excls;
1202 top.atoms = gmx_mtop_global_atoms(mtop);
1203 top.mols = mtop->mols;
1204 top.bIntermolecularInteractions = mtop->bIntermolecularInteractions;
1205 top.symtab = mtop->symtab;
1207 /* We only need to free the moltype and molblock data,
1208 * all other pointers have been copied to top.
1210 * Well, except for the group data, but we can't free those, because they
1211 * are used somewhere even after a call to this function.
1213 for (mt = 0; mt < mtop->nmoltype; mt++)
1215 done_moltype(&mtop->moltype[mt]);
1217 sfree(mtop->moltype);
1219 for (mb = 0; mb < mtop->nmolblock; mb++)
1221 done_molblock(&mtop->molblock[mb]);
1223 sfree(mtop->molblock);