2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2008,2009,2010,2012,2013,2014,2015,2016,2017, 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/math/vectypes.h"
46 #include "gromacs/topology/atoms.h"
47 #include "gromacs/topology/block.h"
48 #include "gromacs/topology/idef.h"
49 #include "gromacs/topology/ifunc.h"
50 #include "gromacs/topology/topology.h"
51 #include "gromacs/topology/topsort.h"
52 #include "gromacs/utility/fatalerror.h"
53 #include "gromacs/utility/real.h"
54 #include "gromacs/utility/smalloc.h"
56 static int gmx_mtop_maxresnr(const gmx_mtop_t *mtop, int maxres_renum)
63 for (mt = 0; mt < mtop->nmoltype; mt++)
65 atoms = &mtop->moltype[mt].atoms;
66 if (atoms->nres > maxres_renum)
68 for (r = 0; r < atoms->nres; r++)
70 if (atoms->resinfo[r].nr > maxresnr)
72 maxresnr = atoms->resinfo[r].nr;
81 static void finalizeMolblocks(gmx_mtop_t *mtop)
85 int residueNumberStart = mtop->maxresnr + 1;
86 for (int mb = 0; mb < mtop->nmolblock; mb++)
88 gmx_molblock_t *molb = &mtop->molblock[mb];
89 int numResPerMol = mtop->moltype[molb->type].atoms.nres;
90 molb->globalAtomStart = atomIndex;
91 molb->globalResidueStart = residueIndex;
92 atomIndex += molb->nmol*molb->natoms_mol;
93 residueIndex += molb->nmol*numResPerMol;
94 molb->globalAtomEnd = atomIndex;
95 molb->residueNumberStart = residueNumberStart;
96 if (numResPerMol <= mtop->maxres_renum)
98 residueNumberStart += molb->nmol*numResPerMol;
103 void gmx_mtop_finalize(gmx_mtop_t *mtop)
107 if (mtop->nmolblock == 1 && mtop->molblock[0].nmol == 1)
109 /* We have a single molecule only, no renumbering needed.
110 * This case also covers an mtop converted from pdb/gro/... input,
111 * so we retain the original residue numbering.
113 mtop->maxres_renum = 0;
117 /* We only renumber single residue molecules. Their intra-molecular
118 * residue numbering is anyhow irrelevant.
120 mtop->maxres_renum = 1;
123 env = getenv("GMX_MAXRESRENUM");
126 sscanf(env, "%d", &mtop->maxres_renum);
128 if (mtop->maxres_renum == -1)
130 /* -1 signals renumber residues in all molecules */
131 mtop->maxres_renum = INT_MAX;
134 mtop->maxresnr = gmx_mtop_maxresnr(mtop, mtop->maxres_renum);
136 finalizeMolblocks(mtop);
139 void gmx_mtop_count_atomtypes(const gmx_mtop_t *mtop, int state, int typecount[])
141 int i, mb, nmol, tpi;
144 for (i = 0; i < mtop->ffparams.atnr; ++i)
148 for (mb = 0; mb < mtop->nmolblock; ++mb)
150 nmol = mtop->molblock[mb].nmol;
151 atoms = &mtop->moltype[mtop->molblock[mb].type].atoms;
152 for (i = 0; i < atoms->nr; ++i)
156 tpi = atoms->atom[i].type;
160 tpi = atoms->atom[i].typeB;
162 typecount[tpi] += nmol;
167 int ncg_mtop(const gmx_mtop_t *mtop)
173 for (mb = 0; mb < mtop->nmolblock; mb++)
176 mtop->molblock[mb].nmol*
177 mtop->moltype[mtop->molblock[mb].type].cgs.nr;
183 int gmx_mtop_nres(const gmx_mtop_t *mtop)
186 for (int mb = 0; mb < mtop->nmolblock; ++mb)
189 mtop->molblock[mb].nmol*
190 mtop->moltype[mtop->molblock[mb].type].atoms.nres;
195 void gmx_mtop_remove_chargegroups(gmx_mtop_t *mtop)
201 for (mt = 0; mt < mtop->nmoltype; mt++)
203 cgs = &mtop->moltype[mt].cgs;
204 if (cgs->nr < mtop->moltype[mt].atoms.nr)
206 cgs->nr = mtop->moltype[mt].atoms.nr;
207 srenew(cgs->index, cgs->nr+1);
208 for (i = 0; i < cgs->nr+1; i++)
216 typedef struct gmx_mtop_atomloop_all
218 const gmx_mtop_t *mtop;
225 } t_gmx_mtop_atomloop_all;
227 gmx_mtop_atomloop_all_t
228 gmx_mtop_atomloop_all_init(const gmx_mtop_t *mtop)
230 struct gmx_mtop_atomloop_all *aloop;
237 &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms;
239 aloop->maxresnr = mtop->maxresnr;
240 aloop->at_local = -1;
241 aloop->at_global = -1;
246 static void gmx_mtop_atomloop_all_destroy(gmx_mtop_atomloop_all_t aloop)
251 gmx_bool gmx_mtop_atomloop_all_next(gmx_mtop_atomloop_all_t aloop,
252 int *at_global, const t_atom **atom)
254 if (aloop == nullptr)
256 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
262 if (aloop->at_local >= aloop->atoms->nr)
264 if (aloop->atoms->nres <= aloop->mtop->maxres_renum)
266 /* Single residue molecule, increase the count with one */
267 aloop->maxresnr += aloop->atoms->nres;
271 if (aloop->mol >= aloop->mtop->molblock[aloop->mblock].nmol)
274 if (aloop->mblock >= aloop->mtop->nmolblock)
276 gmx_mtop_atomloop_all_destroy(aloop);
279 aloop->atoms = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type].atoms;
284 *at_global = aloop->at_global;
285 *atom = &aloop->atoms->atom[aloop->at_local];
290 void gmx_mtop_atomloop_all_names(gmx_mtop_atomloop_all_t aloop,
291 char **atomname, int *resnr, char **resname)
295 *atomname = *(aloop->atoms->atomname[aloop->at_local]);
296 resind_mol = aloop->atoms->atom[aloop->at_local].resind;
297 *resnr = aloop->atoms->resinfo[resind_mol].nr;
298 if (aloop->atoms->nres <= aloop->mtop->maxres_renum)
300 *resnr = aloop->maxresnr + 1 + resind_mol;
302 *resname = *(aloop->atoms->resinfo[resind_mol].name);
305 void gmx_mtop_atomloop_all_moltype(gmx_mtop_atomloop_all_t aloop,
306 gmx_moltype_t **moltype, int *at_mol)
308 *moltype = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type];
309 *at_mol = aloop->at_local;
312 typedef struct gmx_mtop_atomloop_block
314 const gmx_mtop_t *mtop;
318 } t_gmx_mtop_atomloop_block;
320 gmx_mtop_atomloop_block_t
321 gmx_mtop_atomloop_block_init(const gmx_mtop_t *mtop)
323 struct gmx_mtop_atomloop_block *aloop;
329 aloop->atoms = &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms;
330 aloop->at_local = -1;
335 static void gmx_mtop_atomloop_block_destroy(gmx_mtop_atomloop_block_t aloop)
340 gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop,
341 const t_atom **atom, int *nmol)
343 if (aloop == nullptr)
345 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
350 if (aloop->at_local >= aloop->atoms->nr)
353 if (aloop->mblock >= aloop->mtop->nmolblock)
355 gmx_mtop_atomloop_block_destroy(aloop);
358 aloop->atoms = &aloop->mtop->moltype[aloop->mtop->molblock[aloop->mblock].type].atoms;
362 *atom = &aloop->atoms->atom[aloop->at_local];
363 *nmol = aloop->mtop->molblock[aloop->mblock].nmol;
368 typedef struct gmx_mtop_ilistloop
370 const gmx_mtop_t *mtop;
375 gmx_mtop_ilistloop_init(const gmx_mtop_t *mtop)
377 struct gmx_mtop_ilistloop *iloop;
387 static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop)
392 gmx_bool gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop,
393 t_ilist **ilist_mol, int *nmol)
395 if (iloop == nullptr)
397 gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init");
401 if (iloop->mblock >= iloop->mtop->nmolblock)
403 if (iloop->mblock == iloop->mtop->nmolblock &&
404 iloop->mtop->bIntermolecularInteractions)
406 *ilist_mol = iloop->mtop->intermolecular_ilist;
411 gmx_mtop_ilistloop_destroy(iloop);
416 iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
418 *nmol = iloop->mtop->molblock[iloop->mblock].nmol;
422 typedef struct gmx_mtop_ilistloop_all
424 const gmx_mtop_t *mtop;
428 } t_gmx_mtop_ilist_all;
430 gmx_mtop_ilistloop_all_t
431 gmx_mtop_ilistloop_all_init(const gmx_mtop_t *mtop)
433 struct gmx_mtop_ilistloop_all *iloop;
445 static void gmx_mtop_ilistloop_all_destroy(gmx_mtop_ilistloop_all_t iloop)
450 gmx_bool gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop,
451 t_ilist **ilist_mol, int *atnr_offset)
454 if (iloop == nullptr)
456 gmx_incons("gmx_mtop_ilistloop_all_next called without calling gmx_mtop_ilistloop_all_init");
461 iloop->a_offset += iloop->mtop->molblock[iloop->mblock].natoms_mol;
466 /* Inter-molecular interactions, if present, are indexed with
467 * iloop->mblock == iloop->mtop->nmolblock, thus we should separately
468 * check for this value in this conditional.
470 if (iloop->mblock == iloop->mtop->nmolblock ||
471 iloop->mol >= iloop->mtop->molblock[iloop->mblock].nmol)
475 if (iloop->mblock >= iloop->mtop->nmolblock)
477 if (iloop->mblock == iloop->mtop->nmolblock &&
478 iloop->mtop->bIntermolecularInteractions)
480 *ilist_mol = iloop->mtop->intermolecular_ilist;
485 gmx_mtop_ilistloop_all_destroy(iloop);
491 iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
493 *atnr_offset = iloop->a_offset;
498 int gmx_mtop_ftype_count(const gmx_mtop_t *mtop, int ftype)
500 gmx_mtop_ilistloop_t iloop;
506 iloop = gmx_mtop_ilistloop_init(mtop);
507 while (gmx_mtop_ilistloop_next(iloop, &il, &nmol))
509 n += nmol*il[ftype].nr/(1+NRAL(ftype));
512 if (mtop->bIntermolecularInteractions)
514 n += mtop->intermolecular_ilist[ftype].nr/(1+NRAL(ftype));
520 t_block gmx_mtop_global_cgs(const gmx_mtop_t *mtop)
522 t_block cgs_gl, *cgs_mol;
524 gmx_molblock_t *molb;
526 /* In most cases this is too much, but we realloc at the end */
527 snew(cgs_gl.index, mtop->natoms+1);
531 for (mb = 0; mb < mtop->nmolblock; mb++)
533 molb = &mtop->molblock[mb];
534 cgs_mol = &mtop->moltype[molb->type].cgs;
535 for (mol = 0; mol < molb->nmol; mol++)
537 for (cg = 0; cg < cgs_mol->nr; cg++)
539 cgs_gl.index[cgs_gl.nr+1] =
540 cgs_gl.index[cgs_gl.nr] +
541 cgs_mol->index[cg+1] - cgs_mol->index[cg];
546 cgs_gl.nalloc_index = cgs_gl.nr + 1;
547 srenew(cgs_gl.index, cgs_gl.nalloc_index);
552 static void atomcat(t_atoms *dest, t_atoms *src, int copies,
553 int maxres_renum, int *maxresnr)
557 int destnr = dest->nr;
561 dest->haveMass = src->haveMass;
562 dest->haveType = src->haveType;
563 dest->haveCharge = src->haveCharge;
564 dest->haveBState = src->haveBState;
565 dest->havePdbInfo = src->havePdbInfo;
569 dest->haveMass = dest->haveMass && src->haveMass;
570 dest->haveType = dest->haveType && src->haveType;
571 dest->haveCharge = dest->haveCharge && src->haveCharge;
572 dest->haveBState = dest->haveBState && src->haveBState;
573 dest->havePdbInfo = dest->havePdbInfo && src->havePdbInfo;
578 size = destnr+copies*srcnr;
579 srenew(dest->atom, size);
580 srenew(dest->atomname, size);
583 srenew(dest->atomtype, size);
584 if (dest->haveBState)
586 srenew(dest->atomtypeB, size);
589 if (dest->havePdbInfo)
591 srenew(dest->pdbinfo, size);
596 size = dest->nres+copies*src->nres;
597 srenew(dest->resinfo, size);
600 /* residue information */
601 for (l = dest->nres, j = 0; (j < copies); j++, l += src->nres)
603 memcpy((char *) &(dest->resinfo[l]), (char *) &(src->resinfo[0]),
604 (size_t)(src->nres*sizeof(src->resinfo[0])));
607 for (l = destnr, j = 0; (j < copies); j++, l += srcnr)
609 memcpy((char *) &(dest->atom[l]), (char *) &(src->atom[0]),
610 (size_t)(srcnr*sizeof(src->atom[0])));
611 memcpy((char *) &(dest->atomname[l]), (char *) &(src->atomname[0]),
612 (size_t)(srcnr*sizeof(src->atomname[0])));
615 memcpy((char *) &(dest->atomtype[l]), (char *) &(src->atomtype[0]),
616 (size_t)(srcnr*sizeof(src->atomtype[0])));
617 if (dest->haveBState)
619 memcpy((char *) &(dest->atomtypeB[l]), (char *) &(src->atomtypeB[0]),
620 (size_t)(srcnr*sizeof(src->atomtypeB[0])));
623 if (dest->havePdbInfo)
625 memcpy((char *) &(dest->pdbinfo[l]), (char *) &(src->pdbinfo[0]),
626 (size_t)(srcnr*sizeof(src->pdbinfo[0])));
630 /* Increment residue indices */
631 for (l = destnr, j = 0; (j < copies); j++)
633 for (i = 0; (i < srcnr); i++, l++)
635 dest->atom[l].resind = dest->nres+j*src->nres+src->atom[i].resind;
639 if (src->nres <= maxres_renum)
641 /* Single residue molecule, continue counting residues */
642 for (j = 0; (j < copies); j++)
644 for (l = 0; l < src->nres; l++)
647 dest->resinfo[dest->nres+j*src->nres+l].nr = *maxresnr;
652 dest->nres += copies*src->nres;
653 dest->nr += copies*src->nr;
656 t_atoms gmx_mtop_global_atoms(const gmx_mtop_t *mtop)
660 gmx_molblock_t *molb;
662 init_t_atoms(&atoms, 0, FALSE);
664 maxresnr = mtop->maxresnr;
665 for (mb = 0; mb < mtop->nmolblock; mb++)
667 molb = &mtop->molblock[mb];
668 atomcat(&atoms, &mtop->moltype[molb->type].atoms, molb->nmol,
669 mtop->maxres_renum, &maxresnr);
676 * The cat routines below are old code from src/kernel/topcat.c
679 static void blockcat(t_block *dest, t_block *src, int copies)
681 int i, j, l, nra, size;
685 size = (dest->nr+copies*src->nr+1);
686 srenew(dest->index, size);
689 nra = dest->index[dest->nr];
690 for (l = dest->nr, j = 0; (j < copies); j++)
692 for (i = 0; (i < src->nr); i++)
694 dest->index[l++] = nra + src->index[i];
696 nra += src->index[src->nr];
698 dest->nr += copies*src->nr;
699 dest->index[dest->nr] = nra;
702 static void blockacat(t_blocka *dest, t_blocka *src, int copies,
706 int destnr = dest->nr;
707 int destnra = dest->nra;
711 size = (dest->nr+copies*src->nr+1);
712 srenew(dest->index, size);
716 size = (dest->nra+copies*src->nra);
717 srenew(dest->a, size);
720 for (l = destnr, j = 0; (j < copies); j++)
722 for (i = 0; (i < src->nr); i++)
724 dest->index[l++] = dest->nra+src->index[i];
726 dest->nra += src->nra;
728 for (l = destnra, j = 0; (j < copies); j++)
730 for (i = 0; (i < src->nra); i++)
732 dest->a[l++] = dnum+src->a[i];
737 dest->index[dest->nr] = dest->nra;
740 static void ilistcat(int ftype, t_ilist *dest, t_ilist *src, int copies,
747 dest->nalloc = dest->nr + copies*src->nr;
748 srenew(dest->iatoms, dest->nalloc);
750 for (c = 0; c < copies; c++)
752 for (i = 0; i < src->nr; )
754 dest->iatoms[dest->nr++] = src->iatoms[i++];
755 for (a = 0; a < nral; a++)
757 dest->iatoms[dest->nr++] = dnum + src->iatoms[i++];
764 static void set_posres_params(t_idef *idef, gmx_molblock_t *molb,
765 int i0, int a_offset)
771 il = &idef->il[F_POSRES];
773 idef->iparams_posres_nalloc = i1;
774 srenew(idef->iparams_posres, idef->iparams_posres_nalloc);
775 for (i = i0; i < i1; i++)
777 ip = &idef->iparams_posres[i];
778 /* Copy the force constants */
779 *ip = idef->iparams[il->iatoms[i*2]];
780 a_molb = il->iatoms[i*2+1] - a_offset;
781 if (molb->nposres_xA == 0)
783 gmx_incons("Position restraint coordinates are missing");
785 ip->posres.pos0A[XX] = molb->posres_xA[a_molb][XX];
786 ip->posres.pos0A[YY] = molb->posres_xA[a_molb][YY];
787 ip->posres.pos0A[ZZ] = molb->posres_xA[a_molb][ZZ];
788 if (molb->nposres_xB > 0)
790 ip->posres.pos0B[XX] = molb->posres_xB[a_molb][XX];
791 ip->posres.pos0B[YY] = molb->posres_xB[a_molb][YY];
792 ip->posres.pos0B[ZZ] = molb->posres_xB[a_molb][ZZ];
796 ip->posres.pos0B[XX] = ip->posres.pos0A[XX];
797 ip->posres.pos0B[YY] = ip->posres.pos0A[YY];
798 ip->posres.pos0B[ZZ] = ip->posres.pos0A[ZZ];
800 /* Set the parameter index for idef->iparams_posre */
805 static void set_fbposres_params(t_idef *idef, gmx_molblock_t *molb,
806 int i0, int a_offset)
812 il = &idef->il[F_FBPOSRES];
814 idef->iparams_fbposres_nalloc = i1;
815 srenew(idef->iparams_fbposres, idef->iparams_fbposres_nalloc);
816 for (i = i0; i < i1; i++)
818 ip = &idef->iparams_fbposres[i];
819 /* Copy the force constants */
820 *ip = idef->iparams[il->iatoms[i*2]];
821 a_molb = il->iatoms[i*2+1] - a_offset;
822 if (molb->nposres_xA == 0)
824 gmx_incons("Position restraint coordinates are missing");
826 /* Take flat-bottom posres reference from normal position restraints */
827 ip->fbposres.pos0[XX] = molb->posres_xA[a_molb][XX];
828 ip->fbposres.pos0[YY] = molb->posres_xA[a_molb][YY];
829 ip->fbposres.pos0[ZZ] = molb->posres_xA[a_molb][ZZ];
830 /* Note: no B-type for flat-bottom posres */
832 /* Set the parameter index for idef->iparams_posre */
837 static void gen_local_top(const gmx_mtop_t *mtop,
838 bool freeEnergyInteractionsAtEnd,
842 int mb, srcnr, destnr, ftype, natoms, mol, nposre_old, nfbposre_old;
843 gmx_molblock_t *molb;
845 const gmx_ffparams_t *ffp;
848 gmx_mtop_atomloop_all_t aloop;
851 top->atomtypes = mtop->atomtypes;
853 ffp = &mtop->ffparams;
856 idef->ntypes = ffp->ntypes;
857 idef->atnr = ffp->atnr;
858 idef->functype = ffp->functype;
859 idef->iparams = ffp->iparams;
860 idef->iparams_posres = nullptr;
861 idef->iparams_posres_nalloc = 0;
862 idef->iparams_fbposres = nullptr;
863 idef->iparams_fbposres_nalloc = 0;
864 idef->fudgeQQ = ffp->fudgeQQ;
865 idef->cmap_grid = ffp->cmap_grid;
866 idef->ilsort = ilsortUNKNOWN;
868 init_block(&top->cgs);
869 init_blocka(&top->excls);
870 for (ftype = 0; ftype < F_NRE; ftype++)
872 idef->il[ftype].nr = 0;
873 idef->il[ftype].nalloc = 0;
874 idef->il[ftype].iatoms = nullptr;
878 for (mb = 0; mb < mtop->nmolblock; mb++)
880 molb = &mtop->molblock[mb];
881 molt = &mtop->moltype[molb->type];
883 srcnr = molt->atoms.nr;
886 blockcat(&top->cgs, &molt->cgs, molb->nmol);
888 blockacat(&top->excls, &molt->excls, molb->nmol, destnr, srcnr);
890 nposre_old = idef->il[F_POSRES].nr;
891 nfbposre_old = idef->il[F_FBPOSRES].nr;
892 for (ftype = 0; ftype < F_NRE; ftype++)
895 ftype == F_CONSTR && molt->ilist[F_CONSTRNC].nr > 0)
897 /* Merge all constrains into one ilist.
898 * This simplifies the constraint code.
900 for (mol = 0; mol < molb->nmol; mol++)
902 ilistcat(ftype, &idef->il[F_CONSTR], &molt->ilist[F_CONSTR],
903 1, destnr+mol*srcnr, srcnr);
904 ilistcat(ftype, &idef->il[F_CONSTR], &molt->ilist[F_CONSTRNC],
905 1, destnr+mol*srcnr, srcnr);
908 else if (!(bMergeConstr && ftype == F_CONSTRNC))
910 ilistcat(ftype, &idef->il[ftype], &molt->ilist[ftype],
911 molb->nmol, destnr, srcnr);
914 if (idef->il[F_POSRES].nr > nposre_old)
916 /* Executing this line line stops gmxdump -sys working
917 * correctly. I'm not aware there's an elegant fix. */
918 set_posres_params(idef, molb, nposre_old/2, natoms);
920 if (idef->il[F_FBPOSRES].nr > nfbposre_old)
922 set_fbposres_params(idef, molb, nfbposre_old/2, natoms);
925 natoms += molb->nmol*srcnr;
928 if (mtop->bIntermolecularInteractions)
930 for (ftype = 0; ftype < F_NRE; ftype++)
932 ilistcat(ftype, &idef->il[ftype], &mtop->intermolecular_ilist[ftype],
937 if (freeEnergyInteractionsAtEnd && gmx_mtop_bondeds_free_energy(mtop))
939 snew(qA, mtop->natoms);
940 snew(qB, mtop->natoms);
941 aloop = gmx_mtop_atomloop_all_init(mtop);
943 while (gmx_mtop_atomloop_all_next(aloop, &ag, &atom))
948 gmx_sort_ilist_fe(&top->idef, qA, qB);
954 top->idef.ilsort = ilsortNO_FE;
959 gmx_mtop_generate_local_top(const gmx_mtop_t *mtop,
960 bool freeEnergyInteractionsAtEnd)
966 gen_local_top(mtop, freeEnergyInteractionsAtEnd, true, top);
971 t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop, bool freeMTop)
977 gen_local_top(mtop, false, FALSE, <op);
978 ltop.idef.ilsort = ilsortUNKNOWN;
980 top.name = mtop->name;
981 top.idef = ltop.idef;
982 top.atomtypes = ltop.atomtypes;
984 top.excls = ltop.excls;
985 top.atoms = gmx_mtop_global_atoms(mtop);
986 top.mols = mtop->mols;
987 top.bIntermolecularInteractions = mtop->bIntermolecularInteractions;
988 top.symtab = mtop->symtab;
992 // Free pointers that have not been copied to top.
993 for (mt = 0; mt < mtop->nmoltype; mt++)
995 done_moltype(&mtop->moltype[mt]);
997 sfree(mtop->moltype);
999 for (mb = 0; mb < mtop->nmolblock; mb++)
1001 done_molblock(&mtop->molblock[mb]);
1003 sfree(mtop->molblock);
1005 done_gmx_groups_t(&mtop->groups);
1011 std::vector<size_t> get_atom_index(const gmx_mtop_t *mtop)
1014 std::vector<size_t> atom_index;
1015 gmx_mtop_atomloop_block_t aloopb = gmx_mtop_atomloop_block_init(mtop);
1018 while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol))
1020 if (atom->ptype == eptAtom)
1022 atom_index.push_back(j);
1029 void convertAtomsToMtop(t_symtab *symtab,
1034 mtop->symtab = *symtab;
1039 // This snew clears all entries, we should replace it by an initializer
1040 snew(mtop->moltype, mtop->nmoltype);
1041 mtop->moltype[0].atoms = *atoms;
1042 init_block(&mtop->moltype[0].cgs);
1043 init_blocka(&mtop->moltype[0].excls);
1045 mtop->nmolblock = 1;
1046 // This snew clears all entries, we should replace it by an initializer
1047 snew(mtop->molblock, mtop->nmolblock);
1048 mtop->molblock[0].type = 0;
1049 mtop->molblock[0].nmol = 1;
1050 mtop->molblock[0].natoms_mol = atoms->nr;
1052 mtop->bIntermolecularInteractions = FALSE;
1054 mtop->natoms = atoms->nr;
1056 gmx_mtop_finalize(mtop);