2 * This file is part of the GROMACS molecular simulation package.
4 * This file is part of Gromacs Copyright (c) 1991-2008
5 * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
6 * Copyright (c) 2012, by the GROMACS development team, led by
7 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
8 * others, as listed in the AUTHORS file in the top-level source
9 * directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
45 #include "mtop_util.h"
48 #include "gmx_fatal.h"
50 static int gmx_mtop_maxresnr(const gmx_mtop_t
*mtop
,int maxres_renum
)
57 for(mt
=0; mt
<mtop
->nmoltype
; mt
++)
59 atoms
= &mtop
->moltype
[mt
].atoms
;
60 if (atoms
->nres
> maxres_renum
)
62 for(r
=0; r
<atoms
->nres
; r
++)
64 if (atoms
->resinfo
[r
].nr
> maxresnr
)
66 maxresnr
= atoms
->resinfo
[r
].nr
;
75 void gmx_mtop_finalize(gmx_mtop_t
*mtop
)
79 mtop
->maxres_renum
= 1;
81 env
= getenv("GMX_MAXRESRENUM");
84 sscanf(env
,"%d",&mtop
->maxres_renum
);
86 if (mtop
->maxres_renum
== -1)
88 /* -1 signals renumber residues in all molecules */
89 mtop
->maxres_renum
= INT_MAX
;
92 mtop
->maxresnr
= gmx_mtop_maxresnr(mtop
,mtop
->maxres_renum
);
95 int ncg_mtop(const gmx_mtop_t
*mtop
)
101 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
104 mtop
->molblock
[mb
].nmol
*
105 mtop
->moltype
[mtop
->molblock
[mb
].type
].cgs
.nr
;
111 void gmx_mtop_remove_chargegroups(gmx_mtop_t
*mtop
)
117 for(mt
=0; mt
<mtop
->nmoltype
; mt
++)
119 cgs
= &mtop
->moltype
[mt
].cgs
;
120 if (cgs
->nr
< mtop
->moltype
[mt
].atoms
.nr
)
122 cgs
->nr
= mtop
->moltype
[mt
].atoms
.nr
;
123 srenew(cgs
->index
,cgs
->nr
+1);
124 for(i
=0; i
<cgs
->nr
+1; i
++)
140 typedef struct gmx_mtop_atomlookup
142 const gmx_mtop_t
*mtop
;
146 } t_gmx_mtop_atomlookup
;
149 gmx_mtop_atomlookup_t
150 gmx_mtop_atomlookup_init(const gmx_mtop_t
*mtop
)
152 t_gmx_mtop_atomlookup
*alook
;
154 int a_start
,a_end
,na
,na_start
=-1;
159 alook
->nmb
= mtop
->nmolblock
;
161 snew(alook
->mba
,alook
->nmb
);
164 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
166 na
= mtop
->molblock
[mb
].nmol
*mtop
->molblock
[mb
].natoms_mol
;
167 a_end
= a_start
+ na
;
169 alook
->mba
[mb
].a_start
= a_start
;
170 alook
->mba
[mb
].a_end
= a_end
;
171 alook
->mba
[mb
].na_mol
= mtop
->molblock
[mb
].natoms_mol
;
173 /* We start the binary search with the largest block */
174 if (mb
== 0 || na
> na_start
)
176 alook
->mb_start
= mb
;
186 gmx_mtop_atomlookup_t
187 gmx_mtop_atomlookup_settle_init(const gmx_mtop_t
*mtop
)
189 t_gmx_mtop_atomlookup
*alook
;
193 alook
= gmx_mtop_atomlookup_init(mtop
);
195 /* Check if the starting molblock has settle */
196 if (mtop
->moltype
[mtop
->molblock
[alook
->mb_start
].type
].ilist
[F_SETTLE
].nr
== 0)
198 /* Search the largest molblock with settle */
199 alook
->mb_start
= -1;
200 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
202 if (mtop
->moltype
[mtop
->molblock
[mb
].type
].ilist
[F_SETTLE
].nr
> 0)
204 na
= alook
->mba
[mb
].a_end
- alook
->mba
[mb
].a_start
;
205 if (alook
->mb_start
== -1 || na
> na_start
)
207 alook
->mb_start
= mb
;
213 if (alook
->mb_start
== -1)
215 gmx_incons("gmx_mtop_atomlookup_settle_init called without settles");
223 gmx_mtop_atomlookup_destroy(gmx_mtop_atomlookup_t alook
)
229 void gmx_mtop_atomnr_to_atom(const gmx_mtop_atomlookup_t alook
,
234 int a_start
,atnr_mol
;
237 if (atnr_global
< 0 || atnr_global
>= mtop
->natoms
)
239 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)",
240 atnr_global
,0,mtop
->natoms
-1);
246 mb
= alook
->mb_start
;
250 a_start
= alook
->mba
[mb
].a_start
;
251 if (atnr_global
< a_start
)
255 else if (atnr_global
>= alook
->mba
[mb
].a_end
)
263 mb
= ((mb0
+ mb1
+ 1)>>1);
266 atnr_mol
= (atnr_global
- a_start
) % alook
->mba
[mb
].na_mol
;
268 *atom
= &alook
->mtop
->moltype
[alook
->mtop
->molblock
[mb
].type
].atoms
.atom
[atnr_mol
];
271 void gmx_mtop_atomnr_to_ilist(const gmx_mtop_atomlookup_t alook
,
273 t_ilist
**ilist_mol
,int *atnr_offset
)
276 int a_start
,atnr_local
;
279 if (atnr_global
< 0 || atnr_global
>= mtop
->natoms
)
281 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)",
282 atnr_global
,0,mtop
->natoms
-1);
288 mb
= alook
->mb_start
;
292 a_start
= alook
->mba
[mb
].a_start
;
293 if (atnr_global
< a_start
)
297 else if (atnr_global
>= alook
->mba
[mb
].a_end
)
305 mb
= ((mb0
+ mb1
+ 1)>>1);
308 *ilist_mol
= alook
->mtop
->moltype
[alook
->mtop
->molblock
[mb
].type
].ilist
;
310 atnr_local
= (atnr_global
- a_start
) % alook
->mba
[mb
].na_mol
;
312 *atnr_offset
= atnr_global
- atnr_local
;
315 void gmx_mtop_atomnr_to_molblock_ind(const gmx_mtop_atomlookup_t alook
,
317 int *molb
,int *molnr
,int *atnr_mol
)
323 if (atnr_global
< 0 || atnr_global
>= mtop
->natoms
)
325 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)",
326 atnr_global
,0,mtop
->natoms
-1);
332 mb
= alook
->mb_start
;
336 a_start
= alook
->mba
[mb
].a_start
;
337 if (atnr_global
< a_start
)
341 else if (atnr_global
>= alook
->mba
[mb
].a_end
)
349 mb
= ((mb0
+ mb1
+ 1)>>1);
353 *molnr
= (atnr_global
- a_start
) / alook
->mba
[mb
].na_mol
;
354 *atnr_mol
= atnr_global
- a_start
- (*molnr
)*alook
->mba
[mb
].na_mol
;
357 void gmx_mtop_atominfo_global(const gmx_mtop_t
*mtop
,int atnr_global
,
358 char **atomname
,int *resnr
,char **resname
)
360 int mb
,a_start
,a_end
,maxresnr
,at_loc
;
361 gmx_molblock_t
*molb
;
364 if (atnr_global
< 0 || atnr_global
>= mtop
->natoms
)
366 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)",
367 atnr_global
,0,mtop
->natoms
-1);
372 maxresnr
= mtop
->maxresnr
;
377 if (atoms
->nres
<= mtop
->maxres_renum
)
379 /* Single residue molecule, keep counting */
380 maxresnr
+= mtop
->molblock
[mb
].nmol
*atoms
->nres
;
384 atoms
= &mtop
->moltype
[mtop
->molblock
[mb
].type
].atoms
;
386 a_end
= a_start
+ mtop
->molblock
[mb
].nmol
*atoms
->nr
;
388 while (atnr_global
>= a_end
);
390 at_loc
= (atnr_global
- a_start
) % atoms
->nr
;
391 *atomname
= *(atoms
->atomname
[at_loc
]);
392 if (atoms
->nres
> mtop
->maxres_renum
)
394 *resnr
= atoms
->resinfo
[atoms
->atom
[at_loc
].resind
].nr
;
398 /* Single residue molecule, keep counting */
399 *resnr
= maxresnr
+ 1 + (atnr_global
- a_start
)/atoms
->nr
*atoms
->nres
+ atoms
->atom
[at_loc
].resind
;
401 *resname
= *(atoms
->resinfo
[atoms
->atom
[at_loc
].resind
].name
);
404 typedef struct gmx_mtop_atomloop_all
406 const gmx_mtop_t
*mtop
;
413 } t_gmx_mtop_atomloop_all
;
415 gmx_mtop_atomloop_all_t
416 gmx_mtop_atomloop_all_init(const gmx_mtop_t
*mtop
)
418 struct gmx_mtop_atomloop_all
*aloop
;
425 &mtop
->moltype
[mtop
->molblock
[aloop
->mblock
].type
].atoms
;
427 aloop
->maxresnr
= mtop
->maxresnr
;
428 aloop
->at_local
= -1;
429 aloop
->at_global
= -1;
434 static void gmx_mtop_atomloop_all_destroy(gmx_mtop_atomloop_all_t aloop
)
439 gmx_bool
gmx_mtop_atomloop_all_next(gmx_mtop_atomloop_all_t aloop
,
440 int *at_global
,t_atom
**atom
)
444 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
450 if (aloop
->at_local
>= aloop
->atoms
->nr
)
452 if (aloop
->atoms
->nres
<= aloop
->mtop
->maxres_renum
)
454 /* Single residue molecule, increase the count with one */
455 aloop
->maxresnr
+= aloop
->atoms
->nres
;
459 if (aloop
->mol
>= aloop
->mtop
->molblock
[aloop
->mblock
].nmol
)
462 if (aloop
->mblock
>= aloop
->mtop
->nmolblock
)
464 gmx_mtop_atomloop_all_destroy(aloop
);
467 aloop
->atoms
= &aloop
->mtop
->moltype
[aloop
->mtop
->molblock
[aloop
->mblock
].type
].atoms
;
472 *at_global
= aloop
->at_global
;
473 *atom
= &aloop
->atoms
->atom
[aloop
->at_local
];
478 void gmx_mtop_atomloop_all_names(gmx_mtop_atomloop_all_t aloop
,
479 char **atomname
,int *resnr
,char **resname
)
483 *atomname
= *(aloop
->atoms
->atomname
[aloop
->at_local
]);
484 resind_mol
= aloop
->atoms
->atom
[aloop
->at_local
].resind
;
485 *resnr
= aloop
->atoms
->resinfo
[resind_mol
].nr
;
486 if (aloop
->atoms
->nres
<= aloop
->mtop
->maxres_renum
)
488 *resnr
= aloop
->maxresnr
+ 1 + resind_mol
;
490 *resname
= *(aloop
->atoms
->resinfo
[resind_mol
].name
);
493 void gmx_mtop_atomloop_all_moltype(gmx_mtop_atomloop_all_t aloop
,
494 gmx_moltype_t
**moltype
,int *at_mol
)
496 *moltype
= &aloop
->mtop
->moltype
[aloop
->mtop
->molblock
[aloop
->mblock
].type
];
497 *at_mol
= aloop
->at_local
;
500 typedef struct gmx_mtop_atomloop_block
502 const gmx_mtop_t
*mtop
;
506 } t_gmx_mtop_atomloop_block
;
508 gmx_mtop_atomloop_block_t
509 gmx_mtop_atomloop_block_init(const gmx_mtop_t
*mtop
)
511 struct gmx_mtop_atomloop_block
*aloop
;
517 aloop
->atoms
= &mtop
->moltype
[mtop
->molblock
[aloop
->mblock
].type
].atoms
;
518 aloop
->at_local
= -1;
523 static void gmx_mtop_atomloop_block_destroy(gmx_mtop_atomloop_block_t aloop
)
528 gmx_bool
gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop
,
529 t_atom
**atom
,int *nmol
)
533 gmx_incons("gmx_mtop_atomloop_all_next called without calling gmx_mtop_atomloop_all_init");
538 if (aloop
->at_local
>= aloop
->atoms
->nr
)
541 if (aloop
->mblock
>= aloop
->mtop
->nmolblock
)
543 gmx_mtop_atomloop_block_destroy(aloop
);
546 aloop
->atoms
= &aloop
->mtop
->moltype
[aloop
->mtop
->molblock
[aloop
->mblock
].type
].atoms
;
550 *atom
= &aloop
->atoms
->atom
[aloop
->at_local
];
551 *nmol
= aloop
->mtop
->molblock
[aloop
->mblock
].nmol
;
556 typedef struct gmx_mtop_ilistloop
558 const gmx_mtop_t
*mtop
;
563 gmx_mtop_ilistloop_init(const gmx_mtop_t
*mtop
)
565 struct gmx_mtop_ilistloop
*iloop
;
575 static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop
)
580 gmx_bool
gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop
,
581 t_ilist
**ilist_mol
,int *nmol
)
585 gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init");
589 if (iloop
->mblock
== iloop
->mtop
->nmolblock
)
591 gmx_mtop_ilistloop_destroy(iloop
);
596 iloop
->mtop
->moltype
[iloop
->mtop
->molblock
[iloop
->mblock
].type
].ilist
;
598 *nmol
= iloop
->mtop
->molblock
[iloop
->mblock
].nmol
;
602 typedef struct gmx_mtop_ilistloop_all
604 const gmx_mtop_t
*mtop
;
608 } t_gmx_mtop_ilist_all
;
610 gmx_mtop_ilistloop_all_t
611 gmx_mtop_ilistloop_all_init(const gmx_mtop_t
*mtop
)
613 struct gmx_mtop_ilistloop_all
*iloop
;
625 static void gmx_mtop_ilistloop_all_destroy(gmx_mtop_ilistloop_all_t iloop
)
630 gmx_bool
gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop
,
631 t_ilist
**ilist_mol
,int *atnr_offset
)
633 gmx_molblock_t
*molb
;
637 gmx_incons("gmx_mtop_ilistloop_all_next called without calling gmx_mtop_ilistloop_all_init");
642 iloop
->a_offset
+= iloop
->mtop
->molblock
[iloop
->mblock
].natoms_mol
;
647 if (iloop
->mol
>= iloop
->mtop
->molblock
[iloop
->mblock
].nmol
) {
650 if (iloop
->mblock
== iloop
->mtop
->nmolblock
)
652 gmx_mtop_ilistloop_all_destroy(iloop
);
658 iloop
->mtop
->moltype
[iloop
->mtop
->molblock
[iloop
->mblock
].type
].ilist
;
660 *atnr_offset
= iloop
->a_offset
;
665 int gmx_mtop_ftype_count(const gmx_mtop_t
*mtop
,int ftype
)
667 gmx_mtop_ilistloop_t iloop
;
673 iloop
= gmx_mtop_ilistloop_init(mtop
);
674 while (gmx_mtop_ilistloop_next(iloop
,&il
,&nmol
))
676 n
+= nmol
*il
[ftype
].nr
/(1+NRAL(ftype
));
682 t_block
gmx_mtop_global_cgs(const gmx_mtop_t
*mtop
)
684 t_block cgs_gl
,*cgs_mol
;
686 gmx_molblock_t
*molb
;
689 /* In most cases this is too much, but we realloc at the end */
690 snew(cgs_gl
.index
,mtop
->natoms
+1);
694 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
696 molb
= &mtop
->molblock
[mb
];
697 cgs_mol
= &mtop
->moltype
[molb
->type
].cgs
;
698 for(mol
=0; mol
<molb
->nmol
; mol
++)
700 for(cg
=0; cg
<cgs_mol
->nr
; cg
++)
702 cgs_gl
.index
[cgs_gl
.nr
+1] =
703 cgs_gl
.index
[cgs_gl
.nr
] +
704 cgs_mol
->index
[cg
+1] - cgs_mol
->index
[cg
];
709 cgs_gl
.nalloc_index
= cgs_gl
.nr
+ 1;
710 srenew(cgs_gl
.index
,cgs_gl
.nalloc_index
);
715 static void atomcat(t_atoms
*dest
, t_atoms
*src
, int copies
,
716 int maxres_renum
, int *maxresnr
)
724 size
=destnr
+copies
*srcnr
;
725 srenew(dest
->atom
,size
);
726 srenew(dest
->atomname
,size
);
727 srenew(dest
->atomtype
,size
);
728 srenew(dest
->atomtypeB
,size
);
732 size
=dest
->nres
+copies
*src
->nres
;
733 srenew(dest
->resinfo
,size
);
736 /* residue information */
737 for (l
=dest
->nres
,j
=0; (j
<copies
); j
++,l
+=src
->nres
)
739 memcpy((char *) &(dest
->resinfo
[l
]),(char *) &(src
->resinfo
[0]),
740 (size_t)(src
->nres
*sizeof(src
->resinfo
[0])));
743 for (l
=destnr
,j
=0; (j
<copies
); j
++,l
+=srcnr
)
745 memcpy((char *) &(dest
->atomname
[l
]),(char *) &(src
->atomname
[0]),
746 (size_t)(srcnr
*sizeof(src
->atomname
[0])));
747 memcpy((char *) &(dest
->atomtype
[l
]),(char *) &(src
->atomtype
[0]),
748 (size_t)(srcnr
*sizeof(src
->atomtype
[0])));
749 memcpy((char *) &(dest
->atomtypeB
[l
]),(char *) &(src
->atomtypeB
[0]),
750 (size_t)(srcnr
*sizeof(src
->atomtypeB
[0])));
751 memcpy((char *) &(dest
->atom
[l
]),(char *) &(src
->atom
[0]),
752 (size_t)(srcnr
*sizeof(src
->atom
[0])));
755 /* Increment residue indices */
756 for (l
=destnr
,j
=0; (j
<copies
); j
++)
758 for (i
=0; (i
<srcnr
); i
++,l
++)
760 dest
->atom
[l
].resind
= dest
->nres
+j
*src
->nres
+src
->atom
[i
].resind
;
764 if (src
->nres
<= maxres_renum
)
766 /* Single residue molecule, continue counting residues */
767 for (j
=0; (j
<copies
); j
++)
769 for (l
=0; l
<src
->nres
; l
++)
772 dest
->resinfo
[dest
->nres
+j
*src
->nres
+l
].nr
= *maxresnr
;
777 dest
->nres
+= copies
*src
->nres
;
778 dest
->nr
+= copies
*src
->nr
;
781 t_atoms
gmx_mtop_global_atoms(const gmx_mtop_t
*mtop
)
785 gmx_molblock_t
*molb
;
787 init_t_atoms(&atoms
,0,FALSE
);
789 maxresnr
= mtop
->maxresnr
;
790 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
792 molb
= &mtop
->molblock
[mb
];
793 atomcat(&atoms
,&mtop
->moltype
[molb
->type
].atoms
,molb
->nmol
,
794 mtop
->maxres_renum
,&maxresnr
);
800 void gmx_mtop_make_atomic_charge_groups(gmx_mtop_t
*mtop
,
801 gmx_bool bKeepSingleMolCG
)
806 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
808 cgs_mol
= &mtop
->moltype
[mtop
->molblock
[mb
].type
].cgs
;
809 if (!(bKeepSingleMolCG
&& cgs_mol
->nr
== 1))
811 cgs_mol
->nr
= mtop
->molblock
[mb
].natoms_mol
;
812 cgs_mol
->nalloc_index
= cgs_mol
->nr
+ 1;
813 srenew(cgs_mol
->index
,cgs_mol
->nalloc_index
);
814 for(cg
=0; cg
<cgs_mol
->nr
+1; cg
++)
816 cgs_mol
->index
[cg
] = cg
;
823 * The cat routines below are old code from src/kernel/topcat.c
826 static void blockcat(t_block
*dest
,t_block
*src
,int copies
,
833 size
=(dest
->nr
+copies
*src
->nr
+1);
834 srenew(dest
->index
,size
);
837 nra
= dest
->index
[dest
->nr
];
838 for (l
=dest
->nr
,j
=0; (j
<copies
); j
++)
840 for (i
=0; (i
<src
->nr
); i
++)
842 dest
->index
[l
++] = nra
+ src
->index
[i
];
844 nra
+= src
->index
[src
->nr
];
846 dest
->nr
+= copies
*src
->nr
;
847 dest
->index
[dest
->nr
] = nra
;
850 static void blockacat(t_blocka
*dest
,t_blocka
*src
,int copies
,
854 int destnr
= dest
->nr
;
855 int destnra
= dest
->nra
;
859 size
=(dest
->nr
+copies
*src
->nr
+1);
860 srenew(dest
->index
,size
);
864 size
=(dest
->nra
+copies
*src
->nra
);
865 srenew(dest
->a
,size
);
868 for (l
=destnr
,j
=0; (j
<copies
); j
++)
870 for (i
=0; (i
<src
->nr
); i
++)
872 dest
->index
[l
++] = dest
->nra
+src
->index
[i
];
874 dest
->nra
+= src
->nra
;
876 for (l
=destnra
,j
=0; (j
<copies
); j
++)
878 for (i
=0; (i
<src
->nra
); i
++)
880 dest
->a
[l
++] = dnum
+src
->a
[i
];
885 dest
->index
[dest
->nr
] = dest
->nra
;
888 static void ilistcat(int ftype
,t_ilist
*dest
,t_ilist
*src
,int copies
,
895 dest
->nalloc
= dest
->nr
+ copies
*src
->nr
;
896 srenew(dest
->iatoms
,dest
->nalloc
);
898 for(c
=0; c
<copies
; c
++)
900 for(i
=0; i
<src
->nr
; )
902 dest
->iatoms
[dest
->nr
++] = src
->iatoms
[i
++];
903 for(a
=0; a
<nral
; a
++)
905 dest
->iatoms
[dest
->nr
++] = dnum
+ src
->iatoms
[i
++];
912 static void set_posres_params(t_idef
*idef
,gmx_molblock_t
*molb
,
919 il
= &idef
->il
[F_POSRES
];
921 idef
->iparams_posres_nalloc
= i1
;
922 srenew(idef
->iparams_posres
,idef
->iparams_posres_nalloc
);
925 ip
= &idef
->iparams_posres
[i
];
926 /* Copy the force constants */
927 *ip
= idef
->iparams
[il
->iatoms
[i
*2]];
928 a_molb
= il
->iatoms
[i
*2+1] - a_offset
;
929 if (molb
->nposres_xA
== 0)
931 gmx_incons("Position restraint coordinates are missing");
933 ip
->posres
.pos0A
[XX
] = molb
->posres_xA
[a_molb
][XX
];
934 ip
->posres
.pos0A
[YY
] = molb
->posres_xA
[a_molb
][YY
];
935 ip
->posres
.pos0A
[ZZ
] = molb
->posres_xA
[a_molb
][ZZ
];
936 if (molb
->nposres_xB
> 0)
938 ip
->posres
.pos0B
[XX
] = molb
->posres_xB
[a_molb
][XX
];
939 ip
->posres
.pos0B
[YY
] = molb
->posres_xB
[a_molb
][YY
];
940 ip
->posres
.pos0B
[ZZ
] = molb
->posres_xB
[a_molb
][ZZ
];
944 ip
->posres
.pos0B
[XX
] = ip
->posres
.pos0A
[XX
];
945 ip
->posres
.pos0B
[YY
] = ip
->posres
.pos0A
[YY
];
946 ip
->posres
.pos0B
[ZZ
] = ip
->posres
.pos0A
[ZZ
];
948 /* Set the parameter index for idef->iparams_posre */
953 static void gen_local_top(const gmx_mtop_t
*mtop
,const t_inputrec
*ir
,
954 gmx_bool bMergeConstr
,
957 int mb
,srcnr
,destnr
,ftype
,ftype_dest
,mt
,natoms
,mol
,nposre_old
;
958 gmx_molblock_t
*molb
;
960 const gmx_ffparams_t
*ffp
;
963 gmx_mtop_atomloop_all_t aloop
;
967 top
->atomtypes
= mtop
->atomtypes
;
969 ffp
= &mtop
->ffparams
;
972 idef
->ntypes
= ffp
->ntypes
;
973 idef
->atnr
= ffp
->atnr
;
974 idef
->functype
= ffp
->functype
;
975 idef
->iparams
= ffp
->iparams
;
976 idef
->iparams_posres
= NULL
;
977 idef
->iparams_posres_nalloc
= 0;
978 idef
->fudgeQQ
= ffp
->fudgeQQ
;
979 idef
->cmap_grid
= ffp
->cmap_grid
;
980 idef
->ilsort
= ilsortUNKNOWN
;
982 init_block(&top
->cgs
);
983 init_blocka(&top
->excls
);
984 for(ftype
=0; ftype
<F_NRE
; ftype
++)
986 idef
->il
[ftype
].nr
= 0;
987 idef
->il
[ftype
].nalloc
= 0;
988 idef
->il
[ftype
].iatoms
= NULL
;
992 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
994 molb
= &mtop
->molblock
[mb
];
995 molt
= &mtop
->moltype
[molb
->type
];
997 srcnr
= molt
->atoms
.nr
;
1000 blockcat(&top
->cgs
,&molt
->cgs
,molb
->nmol
,destnr
,srcnr
);
1002 blockacat(&top
->excls
,&molt
->excls
,molb
->nmol
,destnr
,srcnr
);
1004 nposre_old
= idef
->il
[F_POSRES
].nr
;
1005 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1008 ftype
== F_CONSTR
&& molt
->ilist
[F_CONSTRNC
].nr
> 0)
1010 /* Merge all constrains into one ilist.
1011 * This simplifies the constraint code.
1013 for(mol
=0; mol
<molb
->nmol
; mol
++) {
1014 ilistcat(ftype
,&idef
->il
[F_CONSTR
],&molt
->ilist
[F_CONSTR
],
1015 1,destnr
+mol
*srcnr
,srcnr
);
1016 ilistcat(ftype
,&idef
->il
[F_CONSTR
],&molt
->ilist
[F_CONSTRNC
],
1017 1,destnr
+mol
*srcnr
,srcnr
);
1020 else if (!(bMergeConstr
&& ftype
== F_CONSTRNC
))
1022 ilistcat(ftype
,&idef
->il
[ftype
],&molt
->ilist
[ftype
],
1023 molb
->nmol
,destnr
,srcnr
);
1026 if (idef
->il
[F_POSRES
].nr
> nposre_old
)
1028 set_posres_params(idef
,molb
,nposre_old
/2,natoms
);
1031 natoms
+= molb
->nmol
*srcnr
;
1036 top
->idef
.ilsort
= ilsortUNKNOWN
;
1040 if (ir
->efep
!= efepNO
&& gmx_mtop_bondeds_free_energy(mtop
))
1042 snew(qA
,mtop
->natoms
);
1043 snew(qB
,mtop
->natoms
);
1044 aloop
= gmx_mtop_atomloop_all_init(mtop
);
1045 while (gmx_mtop_atomloop_all_next(aloop
,&ag
,&atom
))
1050 gmx_sort_ilist_fe(&top
->idef
,qA
,qB
);
1056 top
->idef
.ilsort
= ilsortNO_FE
;
1061 gmx_localtop_t
*gmx_mtop_generate_local_top(const gmx_mtop_t
*mtop
,
1062 const t_inputrec
*ir
)
1064 gmx_localtop_t
*top
;
1068 gen_local_top(mtop
,ir
,TRUE
,top
);
1073 t_topology
gmx_mtop_t_to_t_topology(gmx_mtop_t
*mtop
)
1076 gmx_localtop_t ltop
;
1079 gen_local_top(mtop
,NULL
,FALSE
,<op
);
1081 top
.name
= mtop
->name
;
1082 top
.idef
= ltop
.idef
;
1083 top
.atomtypes
= ltop
.atomtypes
;
1085 top
.excls
= ltop
.excls
;
1086 top
.atoms
= gmx_mtop_global_atoms(mtop
);
1087 top
.mols
= mtop
->mols
;
1088 top
.symtab
= mtop
->symtab
;
1090 /* We only need to free the moltype and molblock data,
1091 * all other pointers have been copied to top.
1093 * Well, except for the group data, but we can't free those, because they
1094 * are used somewhere even after a call to this function.
1096 for(mt
=0; mt
<mtop
->nmoltype
; mt
++)
1098 done_moltype(&mtop
->moltype
[mt
]);
1100 sfree(mtop
->moltype
);
1102 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
1104 done_molblock(&mtop
->molblock
[mb
]);
1106 sfree(mtop
->molblock
);