1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This file is part of Gromacs Copyright (c) 1991-2008
5 * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * To help us fund GROMACS development, we humbly ask that you cite
13 * the research papers on the package. Check out http://www.gromacs.org
16 * Gnomes, ROck Monsters And Chili Sauce
27 #include "domdec_network.h"
32 #include "chargegroup.h"
33 #include "gmx_random.h"
35 #include "mtop_util.h"
38 #include "gmx_ga2la.h"
41 int *index
; /* Index for each atom into il */
42 int *il
; /* ftype|type|a0|...|an|ftype|... */
43 } gmx_reverse_ilist_t
;
52 typedef struct gmx_reverse_top
{
53 gmx_bool bExclRequired
; /* Do we require all exclusions to be assigned? */
54 gmx_bool bConstr
; /* Are there constraints in this revserse top? */
55 gmx_bool bBCheck
; /* All bonded interactions have to be assigned? */
56 gmx_bool bMultiCGmols
; /* Are the multi charge-group molecules? */
57 gmx_reverse_ilist_t
*ril_mt
; /* Reverse ilist for all moltypes */
59 int ilsort
; /* The sorting state of bondeds for free energy */
60 gmx_molblock_ind_t
*mbi
;
62 /* Pointers only used for an error message */
63 gmx_mtop_t
*err_top_global
;
64 gmx_localtop_t
*err_top_local
;
67 static int nral_rt(int ftype
)
69 /* Returns the number of atom entries for il in gmx_reverse_top_t */
73 if (interaction_function
[ftype
].flags
& IF_VSITE
)
75 /* With vsites the reverse topology contains
76 * two extra entries for PBC.
84 static gmx_bool
dd_check_ftype(int ftype
,gmx_bool bBCheck
,gmx_bool bConstr
)
86 return (((interaction_function
[ftype
].flags
& IF_BOND
) &&
87 !(interaction_function
[ftype
].flags
& IF_VSITE
) &&
88 (bBCheck
|| !(interaction_function
[ftype
].flags
& IF_LIMZERO
))) ||
90 (bConstr
&& (ftype
== F_CONSTR
|| ftype
== F_CONSTRNC
)));
93 static void print_error_header(FILE *fplog
,char *moltypename
,int nprint
)
95 fprintf(fplog
, "\nMolecule type '%s'\n",moltypename
);
96 fprintf(stderr
,"\nMolecule type '%s'\n",moltypename
);
98 "the first %d missing interactions, except for exclusions:\n",
101 "the first %d missing interactions, except for exclusions:\n",
105 static void print_missing_interactions_mb(FILE *fplog
,t_commrec
*cr
,
106 gmx_reverse_top_t
*rt
,
108 gmx_reverse_ilist_t
*ril
,
109 int a_start
,int a_end
,
110 int nat_mol
,int nmol
,
113 int nril_mol
,*assigned
,*gatindex
;
114 int ftype
,ftype_j
,nral
,i
,j_mol
,j
,k
,a0
,a0_mol
,mol
,a
,a_gl
;
120 nril_mol
= ril
->index
[nat_mol
];
121 snew(assigned
,nmol
*nril_mol
);
123 gatindex
= cr
->dd
->gatindex
;
124 for(ftype
=0; ftype
<F_NRE
; ftype
++)
126 if (dd_check_ftype(ftype
,rt
->bBCheck
,rt
->bConstr
))
129 il
= &idef
->il
[ftype
];
131 for(i
=0; i
<il
->nr
; i
+=1+nral
)
133 a0
= gatindex
[ia
[1]];
134 /* Check if this interaction is in
135 * the currently checked molblock.
137 if (a0
>= a_start
&& a0
< a_end
)
139 mol
= (a0
- a_start
)/nat_mol
;
140 a0_mol
= (a0
- a_start
) - mol
*nat_mol
;
141 j_mol
= ril
->index
[a0_mol
];
143 while (j_mol
< ril
->index
[a0_mol
+1] && !bFound
)
145 j
= mol
*nril_mol
+ j_mol
;
146 ftype_j
= ril
->il
[j_mol
];
147 /* Here we need to check if this interaction has
148 * not already been assigned, since we could have
149 * multiply defined interactions.
151 if (ftype
== ftype_j
&& ia
[0] == ril
->il
[j_mol
+1] &&
154 /* Check the atoms */
156 for(a
=0; a
<nral
; a
++)
158 if (gatindex
[ia
[1+a
]] !=
159 a_start
+ mol
*nat_mol
+ ril
->il
[j_mol
+2+a
])
169 j_mol
+= 2 + nral_rt(ftype_j
);
173 gmx_incons("Some interactions seem to be assigned multiple times");
181 gmx_sumi(nmol
*nril_mol
,assigned
,cr
);
185 for(mol
=0; mol
<nmol
; mol
++)
188 while (j_mol
< nril_mol
)
190 ftype
= ril
->il
[j_mol
];
192 j
= mol
*nril_mol
+ j_mol
;
193 if (assigned
[j
] == 0 &&
194 !(interaction_function
[ftype
].flags
& IF_VSITE
))
196 if (DDMASTER(cr
->dd
))
200 print_error_header(fplog
,moltypename
,nprint
);
202 fprintf(fplog
, "%20s atoms",
203 interaction_function
[ftype
].longname
);
204 fprintf(stderr
,"%20s atoms",
205 interaction_function
[ftype
].longname
);
206 for(a
=0; a
<nral
; a
++) {
207 fprintf(fplog
, "%5d",ril
->il
[j_mol
+2+a
]+1);
208 fprintf(stderr
,"%5d",ril
->il
[j_mol
+2+a
]+1);
216 fprintf(fplog
, " global");
217 fprintf(stderr
," global");
218 for(a
=0; a
<nral
; a
++)
220 fprintf(fplog
, "%6d",
221 a_start
+mol
*nat_mol
+ril
->il
[j_mol
+2+a
]+1);
222 fprintf(stderr
,"%6d",
223 a_start
+mol
*nat_mol
+ril
->il
[j_mol
+2+a
]+1);
225 fprintf(fplog
, "\n");
226 fprintf(stderr
,"\n");
234 j_mol
+= 2 + nral_rt(ftype
);
241 static void print_missing_interactions_atoms(FILE *fplog
,t_commrec
*cr
,
242 gmx_mtop_t
*mtop
,t_idef
*idef
)
244 int mb
,a_start
,a_end
;
245 gmx_molblock_t
*molb
;
246 gmx_reverse_top_t
*rt
;
248 rt
= cr
->dd
->reverse_top
;
250 /* Print the atoms in the missing interactions per molblock */
252 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
254 molb
= &mtop
->molblock
[mb
];
256 a_end
= a_start
+ molb
->nmol
*molb
->natoms_mol
;
258 print_missing_interactions_mb(fplog
,cr
,rt
,
259 *(mtop
->moltype
[molb
->type
].name
),
260 &rt
->ril_mt
[molb
->type
],
261 a_start
,a_end
,molb
->natoms_mol
,
267 void dd_print_missing_interactions(FILE *fplog
,t_commrec
*cr
,int local_count
, gmx_mtop_t
*top_global
, t_state
*state_local
)
269 int ndiff_tot
,cl
[F_NRE
],n
,ndiff
,rest_global
,rest_local
;
273 gmx_mtop_t
*err_top_global
;
274 gmx_localtop_t
*err_top_local
;
278 err_top_global
= dd
->reverse_top
->err_top_global
;
279 err_top_local
= dd
->reverse_top
->err_top_local
;
283 fprintf(fplog
,"\nNot all bonded interactions have been properly assigned to the domain decomposition cells\n");
287 ndiff_tot
= local_count
- dd
->nbonded_global
;
289 for(ftype
=0; ftype
<F_NRE
; ftype
++)
292 cl
[ftype
] = err_top_local
->idef
.il
[ftype
].nr
/(1+nral
);
295 gmx_sumi(F_NRE
,cl
,cr
);
299 fprintf(fplog
,"\nA list of missing interactions:\n");
300 fprintf(stderr
,"\nA list of missing interactions:\n");
301 rest_global
= dd
->nbonded_global
;
302 rest_local
= local_count
;
303 for(ftype
=0; ftype
<F_NRE
; ftype
++)
305 /* In the reverse and local top all constraints are merged
306 * into F_CONSTR. So in the if statement we skip F_CONSTRNC
307 * and add these constraints when doing F_CONSTR.
309 if (((interaction_function
[ftype
].flags
& IF_BOND
) &&
310 (dd
->reverse_top
->bBCheck
311 || !(interaction_function
[ftype
].flags
& IF_LIMZERO
)))
313 || (dd
->reverse_top
->bConstr
&& ftype
== F_CONSTR
))
316 n
= gmx_mtop_ftype_count(err_top_global
,ftype
);
317 if (ftype
== F_CONSTR
)
319 n
+= gmx_mtop_ftype_count(err_top_global
,F_CONSTRNC
);
321 ndiff
= cl
[ftype
] - n
;
324 sprintf(buf
,"%20s of %6d missing %6d",
325 interaction_function
[ftype
].longname
,n
,-ndiff
);
326 fprintf(fplog
,"%s\n",buf
);
327 fprintf(stderr
,"%s\n",buf
);
330 rest_local
-= cl
[ftype
];
334 ndiff
= rest_local
- rest_global
;
337 sprintf(buf
,"%20s of %6d missing %6d","exclusions",
339 fprintf(fplog
,"%s\n",buf
);
340 fprintf(stderr
,"%s\n",buf
);
344 print_missing_interactions_atoms(fplog
,cr
,err_top_global
,
345 &err_top_local
->idef
);
346 write_dd_pdb("dd_dump_err",0,"dump",top_global
,cr
,
347 -1,state_local
->x
,state_local
->box
);
352 gmx_incons("One or more interactions were multiple assigned in the domain decompostion");
356 gmx_fatal(FARGS
,"%d of the %d bonded interactions could not be calculated because some atoms involved moved further apart than the multi-body cut-off distance (%g nm) or the two-body cut-off distance (%g nm), see option -rdd, for pairs and tabulated bonds also see option -ddcheck",-ndiff_tot
,cr
->dd
->nbonded_global
,dd_cutoff_mbody(cr
->dd
),dd_cutoff_twobody(cr
->dd
));
361 static void global_atomnr_to_moltype_ind(gmx_molblock_ind_t
*mbi
,int i_gl
,
362 int *mb
,int *mt
,int *mol
,int *i_mol
)
367 while (i_gl
>= mbi
->a_end
) {
373 *mol
= (i_gl
- mbi
->a_start
) / mbi
->natoms_mol
;
374 *i_mol
= (i_gl
- mbi
->a_start
) - (*mol
)*mbi
->natoms_mol
;
377 static int count_excls(t_block
*cgs
,t_blocka
*excls
,int *n_intercg_excl
)
379 int n
,n_inter
,cg
,at0
,at1
,at
,excl
,atj
;
383 for(cg
=0; cg
<cgs
->nr
; cg
++)
385 at0
= cgs
->index
[cg
];
386 at1
= cgs
->index
[cg
+1];
387 for(at
=at0
; at
<at1
; at
++)
389 for(excl
=excls
->index
[at
]; excl
<excls
->index
[at
+1]; excl
++)
391 atj
= excls
->a
[excl
];
395 if (atj
< at0
|| atj
>= at1
)
407 static int low_make_reverse_ilist(t_ilist
*il_mt
,t_atom
*atom
,
410 gmx_bool bConstr
,gmx_bool bBCheck
,
411 int *r_index
,int *r_il
,
412 gmx_bool bLinkToAllAtoms
,
415 int ftype
,nral
,i
,j
,nlink
,link
;
423 for(ftype
=0; ftype
<F_NRE
; ftype
++)
425 if ((interaction_function
[ftype
].flags
& (IF_BOND
| IF_VSITE
)) ||
427 (bConstr
&& (ftype
== F_CONSTR
|| ftype
== F_CONSTRNC
))) {
428 bVSite
= (interaction_function
[ftype
].flags
& IF_VSITE
);
432 for(i
=0; i
<il
->nr
; i
+=1+nral
)
439 /* We don't need the virtual sites for the cg-links */
449 /* Couple to the first atom in the interaction */
452 for(link
=0; link
<nlink
; link
++)
457 r_il
[r_index
[a
]+count
[a
]] =
458 (ftype
== F_CONSTRNC
? F_CONSTR
: ftype
);
459 r_il
[r_index
[a
]+count
[a
]+1] = ia
[0];
460 for(j
=1; j
<1+nral
; j
++)
462 /* Store the molecular atom number */
463 r_il
[r_index
[a
]+count
[a
]+1+j
] = ia
[j
];
466 if (interaction_function
[ftype
].flags
& IF_VSITE
)
470 /* Add an entry to iatoms for storing
471 * which of the constructing atoms are
474 r_il
[r_index
[a
]+count
[a
]+2+nral
] = 0;
475 for(j
=2; j
<1+nral
; j
++)
477 if (atom
[ia
[j
]].ptype
== eptVSite
)
479 r_il
[r_index
[a
]+count
[a
]+2+nral
] |= (2<<j
);
482 /* Store vsite pbc atom in a second extra entry */
483 r_il
[r_index
[a
]+count
[a
]+2+nral
+1] =
484 (vsite_pbc
? vsite_pbc
[ftype
-F_VSITE2
][i
/(1+nral
)] : -2);
489 /* We do not count vsites since they are always
490 * uniquely assigned and can be assigned
491 * to multiple nodes with recursive vsites.
494 !(interaction_function
[ftype
].flags
& IF_LIMZERO
))
499 count
[a
] += 2 + nral_rt(ftype
);
508 static int make_reverse_ilist(gmx_moltype_t
*molt
,
510 gmx_bool bConstr
,gmx_bool bBCheck
,
511 gmx_bool bLinkToAllAtoms
,
512 gmx_reverse_ilist_t
*ril_mt
)
514 int nat_mt
,*count
,i
,nint_mt
;
516 /* Count the interactions */
517 nat_mt
= molt
->atoms
.nr
;
519 low_make_reverse_ilist(molt
->ilist
,molt
->atoms
.atom
,vsite_pbc
,
521 bConstr
,bBCheck
,NULL
,NULL
,
522 bLinkToAllAtoms
,FALSE
);
524 snew(ril_mt
->index
,nat_mt
+1);
525 ril_mt
->index
[0] = 0;
526 for(i
=0; i
<nat_mt
; i
++)
528 ril_mt
->index
[i
+1] = ril_mt
->index
[i
] + count
[i
];
531 snew(ril_mt
->il
,ril_mt
->index
[nat_mt
]);
533 /* Store the interactions */
535 low_make_reverse_ilist(molt
->ilist
,molt
->atoms
.atom
,vsite_pbc
,
538 ril_mt
->index
,ril_mt
->il
,
539 bLinkToAllAtoms
,TRUE
);
546 static void destroy_reverse_ilist(gmx_reverse_ilist_t
*ril
)
552 static gmx_reverse_top_t
*make_reverse_top(gmx_mtop_t
*mtop
,gmx_bool bFE
,
553 int ***vsite_pbc_molt
,
555 gmx_bool bBCheck
,int *nint
)
558 gmx_reverse_top_t
*rt
;
564 /* Should we include constraints (for SHAKE) in rt? */
565 rt
->bConstr
= bConstr
;
566 rt
->bBCheck
= bBCheck
;
568 rt
->bMultiCGmols
= FALSE
;
569 snew(nint_mt
,mtop
->nmoltype
);
570 snew(rt
->ril_mt
,mtop
->nmoltype
);
571 rt
->ril_mt_tot_size
= 0;
572 for(mt
=0; mt
<mtop
->nmoltype
; mt
++)
574 molt
= &mtop
->moltype
[mt
];
575 if (molt
->cgs
.nr
> 1)
577 rt
->bMultiCGmols
= TRUE
;
580 /* Make the atom to interaction list for this molecule type */
582 make_reverse_ilist(molt
,vsite_pbc_molt
? vsite_pbc_molt
[mt
] : NULL
,
583 rt
->bConstr
,rt
->bBCheck
,FALSE
,
586 rt
->ril_mt_tot_size
+= rt
->ril_mt
[mt
].index
[molt
->atoms
.nr
];
590 fprintf(debug
,"The total size of the atom to interaction index is %d integers\n",rt
->ril_mt_tot_size
);
594 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
596 *nint
+= mtop
->molblock
[mb
].nmol
*nint_mt
[mtop
->molblock
[mb
].type
];
600 if (bFE
&& gmx_mtop_bondeds_free_energy(mtop
))
602 rt
->ilsort
= ilsortFE_UNSORTED
;
605 rt
->ilsort
= ilsortNO_FE
;
608 /* Make a molblock index for fast searching */
609 snew(rt
->mbi
,mtop
->nmolblock
);
611 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
613 rt
->mbi
[mb
].a_start
= i
;
614 i
+= mtop
->molblock
[mb
].nmol
*mtop
->molblock
[mb
].natoms_mol
;
615 rt
->mbi
[mb
].a_end
= i
;
616 rt
->mbi
[mb
].natoms_mol
= mtop
->molblock
[mb
].natoms_mol
;
617 rt
->mbi
[mb
].type
= mtop
->molblock
[mb
].type
;
623 void dd_make_reverse_top(FILE *fplog
,
624 gmx_domdec_t
*dd
,gmx_mtop_t
*mtop
,
625 gmx_vsite_t
*vsite
,gmx_constr_t constr
,
626 t_inputrec
*ir
,gmx_bool bBCheck
)
628 int mb
,natoms
,n_recursive_vsite
,nexcl
,nexcl_icg
,a
;
629 gmx_molblock_t
*molb
;
634 fprintf(fplog
,"\nLinking all bonded interactions to atoms\n");
637 dd
->reverse_top
= make_reverse_top(mtop
,ir
->efep
!=efepNO
,
638 vsite
? vsite
->vsite_pbc_molt
: NULL
,
640 bBCheck
,&dd
->nbonded_global
);
642 if (dd
->reverse_top
->ril_mt_tot_size
>= 200000 &&
644 mtop
->nmolblock
== 1 && mtop
->molblock
[0].nmol
== 1)
646 /* mtop comes from a pre Gromacs 4 tpr file */
647 const char *note
="NOTE: The tpr file used for this simulation is in an old format, for less memory usage and possibly more performance create a new tpr file with an up to date version of grompp";
650 fprintf(fplog
,"\n%s\n\n",note
);
654 fprintf(stderr
,"\n%s\n\n",note
);
658 dd
->reverse_top
->bExclRequired
= IR_EXCL_FORCES(*ir
);
661 dd
->n_intercg_excl
= 0;
662 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
664 molb
= &mtop
->molblock
[mb
];
665 molt
= &mtop
->moltype
[molb
->type
];
666 nexcl
+= molb
->nmol
*count_excls(&molt
->cgs
,&molt
->excls
,&nexcl_icg
);
667 dd
->n_intercg_excl
+= molb
->nmol
*nexcl_icg
;
669 if (dd
->reverse_top
->bExclRequired
)
671 dd
->nbonded_global
+= nexcl
;
672 if (EEL_FULL(ir
->coulombtype
) && dd
->n_intercg_excl
> 0 && fplog
)
674 fprintf(fplog
,"There are %d inter charge-group exclusions,\n"
675 "will use an extra communication step for exclusion forces for %s\n",
676 dd
->n_intercg_excl
,eel_names
[ir
->coulombtype
]);
680 natoms
= mtop
->natoms
;
682 if (vsite
&& vsite
->n_intercg_vsite
> 0)
686 fprintf(fplog
,"There are %d inter charge-group virtual sites,\n"
687 "will an extra communication step for selected coordinates and forces\n",
688 vsite
->n_intercg_vsite
);
690 init_domdec_vsites(dd
,natoms
);
693 if (dd
->bInterCGcons
)
695 init_domdec_constraints(dd
,natoms
,mtop
,constr
);
703 static inline void add_ifunc(int nral
,t_iatom
*tiatoms
,t_ilist
*il
)
708 if (il
->nr
+1+nral
> il
->nalloc
)
710 il
->nalloc
+= over_alloc_large(il
->nr
+1+nral
);
711 srenew(il
->iatoms
,il
->nalloc
);
713 liatoms
= il
->iatoms
+ il
->nr
;
714 for(k
=0; k
<=nral
; k
++)
716 liatoms
[k
] = tiatoms
[k
];
721 static void add_posres(int mol
,int a_mol
,gmx_molblock_t
*molb
,
722 t_iatom
*iatoms
,t_idef
*idef
)
727 /* This position restraint has not been added yet,
728 * so it's index is the current number of position restraints.
730 n
= idef
->il
[F_POSRES
].nr
/2;
731 if (n
+1 > idef
->iparams_posres_nalloc
)
733 idef
->iparams_posres_nalloc
= over_alloc_dd(n
+1);
734 srenew(idef
->iparams_posres
,idef
->iparams_posres_nalloc
);
736 ip
= &idef
->iparams_posres
[n
];
737 /* Copy the force constants */
738 *ip
= idef
->iparams
[iatoms
[0]];
740 /* Get the position restriant coordinats from the molblock */
741 a_molb
= mol
*molb
->natoms_mol
+ a_mol
;
742 if (a_molb
>= molb
->nposres_xA
)
744 gmx_incons("Not enough position restraint coordinates");
746 ip
->posres
.pos0A
[XX
] = molb
->posres_xA
[a_molb
][XX
];
747 ip
->posres
.pos0A
[YY
] = molb
->posres_xA
[a_molb
][YY
];
748 ip
->posres
.pos0A
[ZZ
] = molb
->posres_xA
[a_molb
][ZZ
];
749 if (molb
->nposres_xB
> 0)
751 ip
->posres
.pos0B
[XX
] = molb
->posres_xB
[a_molb
][XX
];
752 ip
->posres
.pos0B
[YY
] = molb
->posres_xB
[a_molb
][YY
];
753 ip
->posres
.pos0B
[ZZ
] = molb
->posres_xB
[a_molb
][ZZ
];
757 ip
->posres
.pos0B
[XX
] = ip
->posres
.pos0A
[XX
];
758 ip
->posres
.pos0B
[YY
] = ip
->posres
.pos0A
[YY
];
759 ip
->posres
.pos0B
[ZZ
] = ip
->posres
.pos0A
[ZZ
];
761 /* Set the parameter index for idef->iparams_posre */
765 static void add_vsite(gmx_ga2la_t ga2la
,int *index
,int *rtil
,
767 gmx_bool bHomeA
,int a
,int a_gl
,int a_mol
,
769 t_idef
*idef
,int **vsite_pbc
,int *vsite_pbc_nalloc
)
771 int k
,ak_gl
,vsi
,pbc_a_mol
;
772 t_iatom tiatoms
[1+MAXATOMLIST
],*iatoms_r
;
773 int j
,ftype_r
,nral_r
;
776 tiatoms
[0] = iatoms
[0];
780 /* We know the local index of the first atom */
785 /* Convert later in make_local_vsites */
786 tiatoms
[1] = -a_gl
- 1;
789 for(k
=2; k
<1+nral
; k
++)
791 ak_gl
= a_gl
+ iatoms
[k
] - a_mol
;
792 if (!ga2la_get_home(ga2la
,ak_gl
,&tiatoms
[k
]))
794 /* Copy the global index, convert later in make_local_vsites */
795 tiatoms
[k
] = -(ak_gl
+ 1);
799 /* Add this interaction to the local topology */
800 add_ifunc(nral
,tiatoms
,&idef
->il
[ftype
]);
803 vsi
= idef
->il
[ftype
].nr
/(1+nral
) - 1;
804 if (vsi
>= vsite_pbc_nalloc
[ftype
-F_VSITE2
])
806 vsite_pbc_nalloc
[ftype
-F_VSITE2
] = over_alloc_large(vsi
+1);
807 srenew(vsite_pbc
[ftype
-F_VSITE2
],vsite_pbc_nalloc
[ftype
-F_VSITE2
]);
811 pbc_a_mol
= iatoms
[1+nral
+1];
814 /* The pbc flag is one of the following two options:
815 * -2: vsite and all constructing atoms are within the same cg, no pbc
816 * -1: vsite and its first constructing atom are in the same cg, do pbc
818 vsite_pbc
[ftype
-F_VSITE2
][vsi
] = pbc_a_mol
;
822 /* Set the pbc atom for this vsite so we can make its pbc
823 * identical to the rest of the atoms in its charge group.
824 * Since the order of the atoms does not change within a charge
825 * group, we do not need the global to local atom index.
827 vsite_pbc
[ftype
-F_VSITE2
][vsi
] = a
+ pbc_a_mol
- iatoms
[1];
832 /* This vsite is non-home (required for recursion),
833 * and therefore there is no charge group to match pbc with.
834 * But we always turn on full_pbc to assure that higher order
835 * recursion works correctly.
837 vsite_pbc
[ftype
-F_VSITE2
][vsi
] = -1;
843 /* Check for recursion */
844 for(k
=2; k
<1+nral
; k
++)
846 if ((iatoms
[1+nral
] & (2<<k
)) && (tiatoms
[k
] < 0))
848 /* This construction atoms is a vsite and not a home atom */
851 fprintf(debug
,"Constructing atom %d of vsite atom %d is a vsite and non-home\n",iatoms
[k
]+1,a_mol
+1);
853 /* Find the vsite construction */
855 /* Check all interactions assigned to this atom */
856 j
= index
[iatoms
[k
]];
857 while (j
< index
[iatoms
[k
]+1])
860 nral_r
= NRAL(ftype_r
);
861 if (interaction_function
[ftype_r
].flags
& IF_VSITE
)
863 /* Add this vsite (recursion) */
864 add_vsite(ga2la
,index
,rtil
,ftype_r
,nral_r
,
865 FALSE
,-1,a_gl
+iatoms
[k
]-iatoms
[1],iatoms
[k
],
866 rtil
+j
,idef
,vsite_pbc
,vsite_pbc_nalloc
);
879 static void make_la2lc(gmx_domdec_t
*dd
)
881 int *cgindex
,*la2lc
,cg
,a
;
883 cgindex
= dd
->cgindex
;
885 if (dd
->nat_tot
> dd
->la2lc_nalloc
)
887 dd
->la2lc_nalloc
= over_alloc_dd(dd
->nat_tot
);
888 snew(dd
->la2lc
,dd
->la2lc_nalloc
);
892 /* Make the local atom to local cg index */
893 for(cg
=0; cg
<dd
->ncg_tot
; cg
++)
895 for(a
=cgindex
[cg
]; a
<cgindex
[cg
+1]; a
++)
902 static real
dd_dist2(t_pbc
*pbc_null
,rvec
*cg_cm
,const int *la2lc
,int i
,int j
)
908 pbc_dx_aiuc(pbc_null
,cg_cm
[la2lc
[i
]],cg_cm
[la2lc
[j
]],dx
);
912 rvec_sub(cg_cm
[la2lc
[i
]],cg_cm
[la2lc
[j
]],dx
);
918 static int make_local_bondeds(gmx_domdec_t
*dd
,gmx_domdec_zones_t
*zones
,
919 gmx_molblock_t
*molb
,
920 gmx_bool bRCheckMB
,ivec rcheck
,gmx_bool bRCheck2B
,
922 int *la2lc
,t_pbc
*pbc_null
,rvec
*cg_cm
,
923 t_idef
*idef
,gmx_vsite_t
*vsite
)
925 int nzone
,nizone
,ic
,la0
,la1
,i
,i_gl
,mb
,mt
,mol
,i_mol
,j
,ftype
,nral
,d
,k
;
926 int *index
,*rtil
,**vsite_pbc
,*vsite_pbc_nalloc
;
927 t_iatom
*iatoms
,tiatoms
[1+MAXATOMLIST
];
928 gmx_bool bBCheck
,bUse
,bLocal
;
934 gmx_domdec_ns_ranges_t
*izone
;
935 gmx_reverse_top_t
*rt
;
936 gmx_molblock_ind_t
*mbi
;
940 nizone
= zones
->nizone
;
941 izone
= zones
->izone
;
945 if (vsite
&& vsite
->n_intercg_vsite
> 0)
947 vsite_pbc
= vsite
->vsite_pbc_loc
;
948 vsite_pbc_nalloc
= vsite
->vsite_pbc_loc_nalloc
;
953 vsite_pbc_nalloc
= NULL
;
956 rt
= dd
->reverse_top
;
958 bBCheck
= rt
->bBCheck
;
960 /* Clear the counts */
961 for(ftype
=0; ftype
<F_NRE
; ftype
++)
963 idef
->il
[ftype
].nr
= 0;
971 for(ic
=0; ic
<nzone
; ic
++)
973 la0
= dd
->cgindex
[zones
->cg_range
[ic
]];
974 la1
= dd
->cgindex
[zones
->cg_range
[ic
+1]];
975 for(i
=la0
; i
<la1
; i
++)
977 /* Get the global atom number */
978 i_gl
= dd
->gatindex
[i
];
979 global_atomnr_to_moltype_ind(mbi
,i_gl
,&mb
,&mt
,&mol
,&i_mol
);
980 /* Check all interactions assigned to this atom */
981 index
= rt
->ril_mt
[mt
].index
;
982 rtil
= rt
->ril_mt
[mt
].il
;
984 while (j
< index
[i_mol
+1])
989 if (interaction_function
[ftype
].flags
& IF_VSITE
)
991 /* The vsite construction goes where the vsite itself is */
994 add_vsite(dd
->ga2la
,index
,rtil
,ftype
,nral
,
996 iatoms
,idef
,vsite_pbc
,vsite_pbc_nalloc
);
1003 tiatoms
[0] = iatoms
[0];
1007 /* Assign single-body interactions to the home zone */
1012 if (ftype
== F_POSRES
)
1014 add_posres(mol
,i_mol
,&molb
[mb
],tiatoms
,idef
);
1024 /* This is a two-body interaction, we can assign
1025 * analogous to the non-bonded assignments.
1027 if (!ga2la_get(ga2la
,i_gl
+iatoms
[2]-i_mol
,&a_loc
,&kc
))
1037 /* Check zone interaction assignments */
1038 bUse
= ((ic
< nizone
&& ic
<= kc
&&
1039 izone
[ic
].j0
<= kc
&& kc
< izone
[ic
].j1
) ||
1040 (kc
< nizone
&& ic
> kc
&&
1041 izone
[kc
].j0
<= ic
&& ic
< izone
[kc
].j1
));
1046 /* If necessary check the cgcm distance */
1048 dd_dist2(pbc_null
,cg_cm
,la2lc
,
1049 tiatoms
[1],tiatoms
[2]) >= rc2
)
1058 /* Assign this multi-body bonded interaction to
1059 * the local node if we have all the atoms involved
1060 * (local or communicated) and the minimum zone shift
1061 * in each dimension is zero, for dimensions
1062 * with 2 DD cells an extra check may be necessary.
1067 for(k
=1; k
<=nral
&& bUse
; k
++)
1069 bLocal
= ga2la_get(ga2la
,i_gl
+iatoms
[k
]-i_mol
,
1071 if (!bLocal
|| kc
>= zones
->n
)
1073 /* We do not have this atom of this interaction
1074 * locally, or it comes from more than one cell
1082 for(d
=0; d
<DIM
; d
++)
1084 if (zones
->shift
[kc
][d
] == 0)
1096 k_zero
[XX
] && k_zero
[YY
] && k_zero
[ZZ
]);
1099 for(d
=0; (d
<DIM
&& bUse
); d
++)
1101 /* Check if the cg_cm distance falls within
1102 * the cut-off to avoid possible multiple
1103 * assignments of bonded interactions.
1107 dd_dist2(pbc_null
,cg_cm
,la2lc
,
1108 tiatoms
[k_zero
[d
]],tiatoms
[k_plus
[d
]]) >= rc2
)
1117 /* Add this interaction to the local topology */
1118 add_ifunc(nral
,tiatoms
,&idef
->il
[ftype
]);
1119 /* Sum so we can check in global_stat
1120 * if we have everything.
1123 !(interaction_function
[ftype
].flags
& IF_LIMZERO
))
1134 return nbonded_local
;
1137 static int make_local_bondeds_intracg(gmx_domdec_t
*dd
,gmx_molblock_t
*molb
,
1138 t_idef
*idef
,gmx_vsite_t
*vsite
)
1140 int i
,i_gl
,mb
,mt
,mol
,i_mol
,j
,ftype
,nral
,k
;
1141 int *index
,*rtil
,**vsite_pbc
,*vsite_pbc_nalloc
;
1142 t_iatom
*iatoms
,tiatoms
[1+MAXATOMLIST
];
1143 gmx_reverse_top_t
*rt
;
1144 gmx_molblock_ind_t
*mbi
;
1147 if (vsite
&& vsite
->n_intercg_vsite
> 0)
1149 vsite_pbc
= vsite
->vsite_pbc_loc
;
1150 vsite_pbc_nalloc
= vsite
->vsite_pbc_loc_nalloc
;
1155 vsite_pbc_nalloc
= NULL
;
1158 /* Clear the counts */
1159 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1161 idef
->il
[ftype
].nr
= 0;
1165 rt
= dd
->reverse_top
;
1167 if (rt
->ril_mt_tot_size
== 0)
1169 /* There are no interactions to assign */
1170 return nbonded_local
;
1175 for(i
=0; i
<dd
->nat_home
; i
++)
1177 /* Get the global atom number */
1178 i_gl
= dd
->gatindex
[i
];
1179 global_atomnr_to_moltype_ind(mbi
,i_gl
,&mb
,&mt
,&mol
,&i_mol
);
1180 /* Check all interactions assigned to this atom */
1181 index
= rt
->ril_mt
[mt
].index
;
1182 rtil
= rt
->ril_mt
[mt
].il
;
1183 /* Check all interactions assigned to this atom */
1185 while (j
< index
[i_mol
+1])
1190 if (interaction_function
[ftype
].flags
& IF_VSITE
)
1192 /* The vsite construction goes where the vsite itself is */
1193 add_vsite(dd
->ga2la
,index
,rtil
,ftype
,nral
,
1195 iatoms
,idef
,vsite_pbc
,vsite_pbc_nalloc
);
1201 tiatoms
[0] = iatoms
[0];
1203 for(k
=2; k
<=nral
; k
++)
1205 tiatoms
[k
] = i
+ iatoms
[k
] - iatoms
[1];
1207 if (ftype
== F_POSRES
)
1209 add_posres(mol
,i_mol
,&molb
[mb
],tiatoms
,idef
);
1211 /* Add this interaction to the local topology */
1212 add_ifunc(nral
,tiatoms
,&idef
->il
[ftype
]);
1213 /* Sum so we can check in global_stat if we have everything */
1220 return nbonded_local
;
1223 static int make_local_exclusions(gmx_domdec_t
*dd
,gmx_domdec_zones_t
*zones
,
1225 gmx_bool bRCheck
,real rc
,
1226 int *la2lc
,t_pbc
*pbc_null
,rvec
*cg_cm
,
1230 int nizone
,n
,count
,ic
,jla0
,jla1
,jla
;
1231 int cg
,la0
,la1
,la
,a_gl
,mb
,mt
,mol
,a_mol
,j
,aj_mol
;
1236 gmx_molblock_ind_t
*mbi
;
1239 /* Since for RF and PME we need to loop over the exclusions
1240 * we should store each exclusion only once. This is done
1241 * using the same zone scheme as used for neighbor searching.
1242 * The exclusions involving non-home atoms are stored only
1243 * one way: atom j is in the excl list of i only for j > i,
1244 * where i and j are local atom numbers.
1247 lexcls
->nr
= dd
->cgindex
[zones
->izone
[zones
->nizone
-1].cg1
];
1248 if (lexcls
->nr
+1 > lexcls
->nalloc_index
)
1250 lexcls
->nalloc_index
= over_alloc_dd(lexcls
->nr
)+1;
1251 srenew(lexcls
->index
,lexcls
->nalloc_index
);
1254 mbi
= dd
->reverse_top
->mbi
;
1260 if (dd
->n_intercg_excl
)
1262 nizone
= zones
->nizone
;
1270 for(ic
=0; ic
<nizone
; ic
++)
1272 jla0
= dd
->cgindex
[zones
->izone
[ic
].jcg0
];
1273 jla1
= dd
->cgindex
[zones
->izone
[ic
].jcg1
];
1274 for(cg
=zones
->cg_range
[ic
]; cg
<zones
->cg_range
[ic
+1]; cg
++)
1276 /* Here we assume the number of exclusions in one charge group
1277 * is never larger than 1000.
1279 if (n
+1000 > lexcls
->nalloc_a
)
1281 lexcls
->nalloc_a
= over_alloc_large(n
+1000);
1282 srenew(lexcls
->a
,lexcls
->nalloc_a
);
1284 la0
= dd
->cgindex
[cg
];
1285 la1
= dd
->cgindex
[cg
+1];
1286 if (GET_CGINFO_EXCL_INTER(fr
->cginfo
[cg
]) ||
1287 !GET_CGINFO_EXCL_INTRA(fr
->cginfo
[cg
]))
1289 /* Copy the exclusions from the global top */
1290 for(la
=la0
; la
<la1
; la
++) {
1291 lexcls
->index
[la
] = n
;
1292 a_gl
= dd
->gatindex
[la
];
1293 global_atomnr_to_moltype_ind(mbi
,a_gl
,&mb
,&mt
,&mol
,&a_mol
);
1294 excls
= &mtop
->moltype
[mt
].excls
;
1295 for(j
=excls
->index
[a_mol
]; j
<excls
->index
[a_mol
+1]; j
++)
1297 aj_mol
= excls
->a
[j
];
1298 /* This computation of jla is only correct intra-cg */
1299 jla
= la
+ aj_mol
- a_mol
;
1300 if (jla
>= la0
&& jla
< la1
)
1302 /* This is an intra-cg exclusion. We can skip
1303 * the global indexing and distance checking.
1305 /* Intra-cg exclusions are only required
1306 * for the home zone.
1310 lexcls
->a
[n
++] = jla
;
1311 /* Check to avoid double counts */
1320 /* This is a inter-cg exclusion */
1321 /* Since exclusions are pair interactions,
1322 * just like non-bonded interactions,
1323 * they can be assigned properly up
1324 * to the DD cutoff (not cutoff_min as
1325 * for the other bonded interactions).
1327 if (ga2la_get(ga2la
,a_gl
+aj_mol
-a_mol
,&jla
,&cell
))
1329 if (ic
== 0 && cell
== 0)
1331 lexcls
->a
[n
++] = jla
;
1332 /* Check to avoid double counts */
1338 else if (jla
>= jla0
&& jla
< jla1
&&
1340 dd_dist2(pbc_null
,cg_cm
,la2lc
,la
,jla
) < rc2
))
1342 /* jla > la, since jla0 > la */
1343 lexcls
->a
[n
++] = jla
;
1353 /* There are no inter-cg excls and this cg is self-excluded.
1354 * These exclusions are only required for zone 0,
1355 * since other zones do not see themselves.
1359 for(la
=la0
; la
<la1
; la
++)
1361 lexcls
->index
[la
] = n
;
1362 for(j
=la0
; j
<la1
; j
++)
1367 count
+= ((la1
- la0
)*(la1
- la0
- 1))/2;
1371 /* We don't need exclusions for this cg */
1372 for(la
=la0
; la
<la1
; la
++)
1374 lexcls
->index
[la
] = n
;
1380 if (dd
->n_intercg_excl
== 0)
1382 /* There are no exclusions involving non-home charge groups,
1383 * but we need to set the indices for neighborsearching.
1385 la0
= dd
->cgindex
[zones
->izone
[0].cg1
];
1386 for(la
=la0
; la
<lexcls
->nr
; la
++)
1388 lexcls
->index
[la
] = n
;
1391 lexcls
->index
[lexcls
->nr
] = n
;
1393 if (dd
->n_intercg_excl
== 0)
1395 /* nr is only used to loop over the exclusions for Ewald and RF,
1396 * so we can set it to the number of home atoms for efficiency.
1398 lexcls
->nr
= dd
->cgindex
[zones
->izone
[0].cg1
];
1402 fprintf(debug
,"We have %d exclusions, check count %d\n",
1409 void dd_make_local_cgs(gmx_domdec_t
*dd
,t_block
*lcgs
)
1411 lcgs
->nr
= dd
->ncg_tot
;
1412 lcgs
->index
= dd
->cgindex
;
1415 void dd_make_local_top(FILE *fplog
,
1416 gmx_domdec_t
*dd
,gmx_domdec_zones_t
*zones
,
1417 int npbcdim
,matrix box
,
1418 rvec cellsize_min
,ivec npulse
,
1419 t_forcerec
*fr
,gmx_vsite_t
*vsite
,
1420 gmx_mtop_t
*mtop
,gmx_localtop_t
*ltop
)
1422 gmx_bool bUniqueExcl
,bRCheckMB
,bRCheck2B
,bRCheckExcl
;
1426 t_pbc pbc
,*pbc_null
=NULL
;
1430 fprintf(debug
,"Making local topology\n");
1433 dd_make_local_cgs(dd
,<op
->cgs
);
1437 bRCheckExcl
= FALSE
;
1439 if (!dd
->reverse_top
->bMultiCGmols
)
1441 /* We don't need checks, assign all interactions with local atoms */
1443 dd
->nbonded_local
= make_local_bondeds_intracg(dd
,mtop
->molblock
,
1448 /* We need to check to which cell bondeds should be assigned */
1449 rc
= dd_cutoff_twobody(dd
);
1452 fprintf(debug
,"Two-body bonded cut-off distance is %g\n",rc
);
1455 /* Should we check cg_cm distances when assigning bonded interactions? */
1456 for(d
=0; d
<DIM
; d
++)
1459 /* Only need to check for dimensions where the part of the box
1460 * that is not communicated is smaller than the cut-off.
1462 if (d
< npbcdim
&& dd
->nc
[d
] > 1 &&
1463 (dd
->nc
[d
] - npulse
[d
])*cellsize_min
[d
] < 2*rc
)
1470 /* Check for interactions between two atoms,
1471 * where we can allow interactions up to the cut-off,
1472 * instead of up to the smallest cell dimension.
1479 "dim %d cellmin %f bonded rcheck[%d] = %d, bRCheck2B = %d\n",
1480 d
,cellsize_min
[d
],d
,rcheck
[d
],bRCheck2B
);
1483 if (dd
->reverse_top
->bExclRequired
)
1485 bRCheckExcl
= bRCheck2B
;
1489 /* If we don't have forces on exclusions,
1490 * we don't care about exclusions being assigned mulitple times.
1492 bRCheckExcl
= FALSE
;
1494 if (bRCheckMB
|| bRCheck2B
)
1499 set_pbc_dd(&pbc
,fr
->ePBC
,dd
,TRUE
,box
);
1508 dd
->nbonded_local
= make_local_bondeds(dd
,zones
,mtop
->molblock
,
1509 bRCheckMB
,rcheck
,bRCheck2B
,rc
,
1515 /* The ilist is not sorted yet,
1516 * we can only do this when we have the charge arrays.
1518 ltop
->idef
.ilsort
= ilsortUNKNOWN
;
1520 nexcl
= make_local_exclusions(dd
,zones
,mtop
,bRCheckExcl
,
1521 rc
,dd
->la2lc
,pbc_null
,fr
->cg_cm
,
1524 if (dd
->reverse_top
->bExclRequired
)
1526 dd
->nbonded_local
+= nexcl
;
1529 ltop
->atomtypes
= mtop
->atomtypes
;
1531 /* For an error message only */
1532 dd
->reverse_top
->err_top_global
= mtop
;
1533 dd
->reverse_top
->err_top_local
= ltop
;
1536 void dd_sort_local_top(gmx_domdec_t
*dd
,t_mdatoms
*mdatoms
,
1537 gmx_localtop_t
*ltop
)
1539 if (dd
->reverse_top
->ilsort
== ilsortNO_FE
)
1541 ltop
->idef
.ilsort
= ilsortNO_FE
;
1545 gmx_sort_ilist_fe(<op
->idef
,mdatoms
->chargeA
,mdatoms
->chargeB
);
1549 gmx_localtop_t
*dd_init_local_top(gmx_mtop_t
*top_global
)
1551 gmx_localtop_t
*top
;
1556 top
->idef
.ntypes
= top_global
->ffparams
.ntypes
;
1557 top
->idef
.atnr
= top_global
->ffparams
.atnr
;
1558 top
->idef
.functype
= top_global
->ffparams
.functype
;
1559 top
->idef
.iparams
= top_global
->ffparams
.iparams
;
1560 top
->idef
.fudgeQQ
= top_global
->ffparams
.fudgeQQ
;
1561 top
->idef
.cmap_grid
= top_global
->ffparams
.cmap_grid
;
1563 for(i
=0; i
<F_NRE
; i
++)
1565 top
->idef
.il
[i
].iatoms
= NULL
;
1566 top
->idef
.il
[i
].nalloc
= 0;
1568 top
->idef
.ilsort
= ilsortUNKNOWN
;
1573 void dd_init_local_state(gmx_domdec_t
*dd
,
1574 t_state
*state_global
,t_state
*state_local
)
1580 buf
[0] = state_global
->flags
;
1581 buf
[1] = state_global
->ngtc
;
1582 buf
[2] = state_global
->nnhpres
;
1583 buf
[3] = state_global
->nhchainlength
;
1585 dd_bcast(dd
,4*sizeof(int),buf
);
1587 init_state(state_local
,0,buf
[1],buf
[2],buf
[3]);
1588 state_local
->flags
= buf
[0];
1590 /* With Langevin Dynamics we need to make proper storage space
1591 * in the global and local state for the random numbers.
1593 if (state_local
->flags
& (1<<estLD_RNG
))
1595 if (DDMASTER(dd
) && state_global
->nrngi
> 1)
1597 state_global
->nrng
= dd
->nnodes
*gmx_rng_n();
1598 srenew(state_global
->ld_rng
,state_global
->nrng
);
1600 state_local
->nrng
= gmx_rng_n();
1601 snew(state_local
->ld_rng
,state_local
->nrng
);
1603 if (state_local
->flags
& (1<<estLD_RNGI
))
1605 if (DDMASTER(dd
) && state_global
->nrngi
> 1)
1607 state_global
->nrngi
= dd
->nnodes
;
1608 srenew(state_global
->ld_rngi
,state_global
->nrngi
);
1610 snew(state_local
->ld_rngi
,1);
1614 static void check_link(t_blocka
*link
,int cg_gl
,int cg_gl_j
)
1620 for(k
=link
->index
[cg_gl
]; k
<link
->index
[cg_gl
+1]; k
++)
1622 if (link
->a
[k
] == cg_gl_j
)
1629 /* Add this charge group link */
1630 if (link
->index
[cg_gl
+1]+1 > link
->nalloc_a
)
1632 link
->nalloc_a
= over_alloc_large(link
->index
[cg_gl
+1]+1);
1633 srenew(link
->a
,link
->nalloc_a
);
1635 link
->a
[link
->index
[cg_gl
+1]] = cg_gl_j
;
1636 link
->index
[cg_gl
+1]++;
1640 static int *make_at2cg(t_block
*cgs
)
1644 snew(at2cg
,cgs
->index
[cgs
->nr
]);
1645 for(cg
=0; cg
<cgs
->nr
; cg
++)
1647 for(a
=cgs
->index
[cg
]; a
<cgs
->index
[cg
+1]; a
++)
1656 t_blocka
*make_charge_group_links(gmx_mtop_t
*mtop
,gmx_domdec_t
*dd
,
1657 cginfo_mb_t
*cginfo_mb
)
1659 gmx_reverse_top_t
*rt
;
1660 int mb
,cg_offset
,cg
,cg_gl
,a
,aj
,i
,j
,ftype
,nral
,nlink_mol
,mol
,ncgi
;
1661 gmx_molblock_t
*molb
;
1662 gmx_moltype_t
*molt
;
1666 gmx_reverse_ilist_t ril
;
1668 cginfo_mb_t
*cgi_mb
;
1670 /* For each charge group make a list of other charge groups
1671 * in the system that a linked to it via bonded interactions
1672 * which are also stored in reverse_top.
1675 rt
= dd
->reverse_top
;
1678 snew(link
->index
,ncg_mtop(mtop
)+1);
1685 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
1687 molb
= &mtop
->molblock
[mb
];
1688 if (molb
->nmol
== 0)
1692 molt
= &mtop
->moltype
[molb
->type
];
1694 excls
= &molt
->excls
;
1695 a2c
= make_at2cg(cgs
);
1696 /* Make a reverse ilist in which the interactions are linked
1697 * to all atoms, not only the first atom as in gmx_reverse_top.
1698 * The constraints are discarded here.
1700 make_reverse_ilist(molt
,NULL
,FALSE
,FALSE
,TRUE
,&ril
);
1702 cgi_mb
= &cginfo_mb
[mb
];
1704 for(cg
=0; cg
<cgs
->nr
; cg
++)
1706 cg_gl
= cg_offset
+ cg
;
1707 link
->index
[cg_gl
+1] = link
->index
[cg_gl
];
1708 for(a
=cgs
->index
[cg
]; a
<cgs
->index
[cg
+1]; a
++)
1711 while (i
< ril
.index
[a
+1])
1713 ftype
= ril
.il
[i
++];
1715 /* Skip the ifunc index */
1717 for(j
=0; j
<nral
; j
++)
1722 check_link(link
,cg_gl
,cg_offset
+a2c
[aj
]);
1725 i
+= nral_rt(ftype
);
1727 if (rt
->bExclRequired
)
1729 /* Exclusions always go both ways */
1730 for(j
=excls
->index
[a
]; j
<excls
->index
[a
+1]; j
++)
1735 check_link(link
,cg_gl
,cg_offset
+a2c
[aj
]);
1740 if (link
->index
[cg_gl
+1] - link
->index
[cg_gl
] > 0)
1742 SET_CGINFO_BOND_INTER(cgi_mb
->cginfo
[cg
]);
1746 nlink_mol
= link
->index
[cg_offset
+cgs
->nr
] - link
->index
[cg_offset
];
1748 cg_offset
+= cgs
->nr
;
1750 destroy_reverse_ilist(&ril
);
1755 fprintf(debug
,"molecule type '%s' %d cgs has %d cg links through bonded interac.\n",*molt
->name
,cgs
->nr
,nlink_mol
);
1760 /* Copy the data for the rest of the molecules in this block */
1761 link
->nalloc_a
+= (molb
->nmol
- 1)*nlink_mol
;
1762 srenew(link
->a
,link
->nalloc_a
);
1763 for(mol
=1; mol
<molb
->nmol
; mol
++)
1765 for(cg
=0; cg
<cgs
->nr
; cg
++)
1767 cg_gl
= cg_offset
+ cg
;
1768 link
->index
[cg_gl
+1] =
1769 link
->index
[cg_gl
+1-cgs
->nr
] + nlink_mol
;
1770 for(j
=link
->index
[cg_gl
]; j
<link
->index
[cg_gl
+1]; j
++)
1772 link
->a
[j
] = link
->a
[j
-nlink_mol
] + cgs
->nr
;
1774 if (link
->index
[cg_gl
+1] - link
->index
[cg_gl
] > 0 &&
1775 cg_gl
- cgi_mb
->cg_start
< cgi_mb
->cg_mod
)
1777 SET_CGINFO_BOND_INTER(cgi_mb
->cginfo
[cg_gl
- cgi_mb
->cg_start
]);
1781 cg_offset
+= cgs
->nr
;
1788 fprintf(debug
,"Of the %d charge groups %d are linked via bonded interactions\n",ncg_mtop(mtop
),ncgi
);
1794 static void bonded_cg_distance_mol(gmx_moltype_t
*molt
,int *at2cg
,
1795 gmx_bool bBCheck
,gmx_bool bExcl
,rvec
*cg_cm
,
1796 real
*r_2b
,int *ft2b
,int *a2_1
,int *a2_2
,
1797 real
*r_mb
,int *ftmb
,int *am_1
,int *am_2
)
1799 int ftype
,nral
,i
,j
,ai
,aj
,cgi
,cgj
;
1802 real r2_2b
,r2_mb
,rij2
;
1806 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1808 if (dd_check_ftype(ftype
,bBCheck
,FALSE
))
1810 il
= &molt
->ilist
[ftype
];
1814 for(i
=0; i
<il
->nr
; i
+=1+nral
)
1816 for(ai
=0; ai
<nral
; ai
++)
1818 cgi
= at2cg
[il
->iatoms
[i
+1+ai
]];
1819 for(aj
=0; aj
<nral
; aj
++) {
1820 cgj
= at2cg
[il
->iatoms
[i
+1+aj
]];
1823 rij2
= distance2(cg_cm
[cgi
],cg_cm
[cgj
]);
1824 if (nral
== 2 && rij2
> r2_2b
)
1828 *a2_1
= il
->iatoms
[i
+1+ai
];
1829 *a2_2
= il
->iatoms
[i
+1+aj
];
1831 if (nral
> 2 && rij2
> r2_mb
)
1835 *am_1
= il
->iatoms
[i
+1+ai
];
1836 *am_2
= il
->iatoms
[i
+1+aj
];
1847 excls
= &molt
->excls
;
1848 for(ai
=0; ai
<excls
->nr
; ai
++)
1851 for(j
=excls
->index
[ai
]; j
<excls
->index
[ai
+1]; j
++) {
1852 cgj
= at2cg
[excls
->a
[j
]];
1855 rij2
= distance2(cg_cm
[cgi
],cg_cm
[cgj
]);
1865 *r_2b
= sqrt(r2_2b
);
1866 *r_mb
= sqrt(r2_mb
);
1869 static void get_cgcm_mol(gmx_moltype_t
*molt
,gmx_ffparams_t
*ffparams
,
1870 int ePBC
,t_graph
*graph
,matrix box
,
1872 rvec
*x
,rvec
*xs
,rvec
*cg_cm
)
1876 if (ePBC
!= epbcNONE
)
1878 mk_mshift(NULL
,graph
,ePBC
,box
,x
);
1880 shift_x(graph
,box
,x
,xs
);
1881 /* By doing an extra mk_mshift the molecules that are broken
1882 * because they were e.g. imported from another software
1883 * will be made whole again. Such are the healing powers
1886 mk_mshift(NULL
,graph
,ePBC
,box
,xs
);
1890 /* We copy the coordinates so the original coordinates remain
1891 * unchanged, just to be 100% sure that we do not affect
1892 * binary reproducibility of simulations.
1894 n
= molt
->cgs
.index
[molt
->cgs
.nr
];
1897 copy_rvec(x
[i
],xs
[i
]);
1903 construct_vsites(NULL
,vsite
,xs
,NULL
,0.0,NULL
,
1904 ffparams
->iparams
,molt
->ilist
,
1905 epbcNONE
,TRUE
,NULL
,NULL
,NULL
);
1908 calc_cgcm(NULL
,0,molt
->cgs
.nr
,&molt
->cgs
,xs
,cg_cm
);
1911 static int have_vsite_molt(gmx_moltype_t
*molt
)
1917 for(i
=0; i
<F_NRE
; i
++)
1919 if ((interaction_function
[i
].flags
& IF_VSITE
) &&
1920 molt
->ilist
[i
].nr
> 0) {
1928 void dd_bonded_cg_distance(FILE *fplog
,
1929 gmx_domdec_t
*dd
,gmx_mtop_t
*mtop
,
1930 t_inputrec
*ir
,rvec
*x
,matrix box
,
1932 real
*r_2b
,real
*r_mb
)
1934 gmx_bool bExclRequired
;
1935 int mb
,cg_offset
,at_offset
,*at2cg
,mol
;
1938 gmx_molblock_t
*molb
;
1939 gmx_moltype_t
*molt
;
1941 real rmol_2b
,rmol_mb
;
1942 int ft2b
=-1,a_2b_1
=-1,a_2b_2
=-1,ftmb
=-1,a_mb_1
=-1,a_mb_2
=-1;
1943 int ftm2b
=-1,amol_2b_1
=-1,amol_2b_2
=-1,ftmmb
=-1,amol_mb_1
=-1,amol_mb_2
=-1;
1945 bExclRequired
= IR_EXCL_FORCES(*ir
);
1947 /* For gmx_vsite_t everything 0 should work (without pbc) */
1954 for(mb
=0; mb
<mtop
->nmolblock
; mb
++)
1956 molb
= &mtop
->molblock
[mb
];
1957 molt
= &mtop
->moltype
[molb
->type
];
1958 if (molt
->cgs
.nr
== 1 || molb
->nmol
== 0)
1960 cg_offset
+= molb
->nmol
*molt
->cgs
.nr
;
1961 at_offset
+= molb
->nmol
*molt
->atoms
.nr
;
1965 if (ir
->ePBC
!= epbcNONE
)
1967 mk_graph_ilist(NULL
,molt
->ilist
,0,molt
->atoms
.nr
,FALSE
,FALSE
,
1971 at2cg
= make_at2cg(&molt
->cgs
);
1972 snew(xs
,molt
->atoms
.nr
);
1973 snew(cg_cm
,molt
->cgs
.nr
);
1974 for(mol
=0; mol
<molb
->nmol
; mol
++)
1976 get_cgcm_mol(molt
,&mtop
->ffparams
,ir
->ePBC
,&graph
,box
,
1977 have_vsite_molt(molt
) ? vsite
: NULL
,
1978 x
+at_offset
,xs
,cg_cm
);
1980 bonded_cg_distance_mol(molt
,at2cg
,bBCheck
,bExclRequired
,cg_cm
,
1981 &rmol_2b
,&ftm2b
,&amol_2b_1
,&amol_2b_2
,
1982 &rmol_mb
,&ftmmb
,&amol_mb_1
,&amol_mb_2
);
1983 if (rmol_2b
> *r_2b
)
1987 a_2b_1
= at_offset
+ amol_2b_1
;
1988 a_2b_2
= at_offset
+ amol_2b_2
;
1990 if (rmol_mb
> *r_mb
)
1994 a_mb_1
= at_offset
+ amol_mb_1
;
1995 a_mb_2
= at_offset
+ amol_mb_2
;
1998 cg_offset
+= molt
->cgs
.nr
;
1999 at_offset
+= molt
->atoms
.nr
;
2004 if (ir
->ePBC
!= epbcNONE
)
2013 if (fplog
&& (ft2b
>= 0 || ftmb
>= 0))
2016 "Initial maximum inter charge-group distances:\n");
2020 " two-body bonded interactions: %5.3f nm, %s, atoms %d %d\n",
2021 *r_2b
,interaction_function
[ft2b
].longname
,
2027 " multi-body bonded interactions: %5.3f nm, %s, atoms %d %d\n",
2028 *r_mb
,interaction_function
[ftmb
].longname
,