Merge branch release-5-1
[alexxy/gromacs.git] / src / gromacs / mdlib / constr.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
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.
15  *
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.
20  *
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.
25  *
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.
33  *
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.
36  */
37 #include "gmxpre.h"
38
39 #include "constr.h"
40
41 #include <assert.h>
42 #include <stdlib.h>
43
44 #include <cmath>
45
46 #include <algorithm>
47
48 #include "gromacs/domdec/domdec.h"
49 #include "gromacs/domdec/domdec_struct.h"
50 #include "gromacs/essentialdynamics/edsam.h"
51 #include "gromacs/fileio/confio.h"
52 #include "gromacs/fileio/gmxfio.h"
53 #include "gromacs/fileio/pdbio.h"
54 #include "gromacs/gmxlib/nrnb.h"
55 #include "gromacs/math/utilities.h"
56 #include "gromacs/math/vec.h"
57 #include "gromacs/mdlib/gmx_omp_nthreads.h"
58 #include "gromacs/mdlib/mdrun.h"
59 #include "gromacs/mdlib/splitter.h"
60 #include "gromacs/mdtypes/commrec.h"
61 #include "gromacs/mdtypes/inputrec.h"
62 #include "gromacs/mdtypes/md_enums.h"
63 #include "gromacs/pbcutil/pbc.h"
64 #include "gromacs/pulling/pull.h"
65 #include "gromacs/topology/block.h"
66 #include "gromacs/topology/invblock.h"
67 #include "gromacs/topology/mtop_util.h"
68 #include "gromacs/utility/exceptions.h"
69 #include "gromacs/utility/fatalerror.h"
70 #include "gromacs/utility/pleasecite.h"
71 #include "gromacs/utility/smalloc.h"
72 #include "gromacs/utility/txtdump.h"
73
74 typedef struct gmx_constr {
75     int                ncon_tot;       /* The total number of constraints    */
76     int                nflexcon;       /* The number of flexible constraints */
77     int                n_at2con_mt;    /* The size of at2con = #moltypes     */
78     t_blocka          *at2con_mt;      /* A list of atoms to constraints     */
79     int                n_at2settle_mt; /* The size of at2settle = #moltypes  */
80     int              **at2settle_mt;   /* A list of atoms to settles         */
81     gmx_bool           bInterCGsettles;
82     gmx_lincsdata_t    lincsd;         /* LINCS data                         */
83     gmx_shakedata_t    shaked;         /* SHAKE data                         */
84     gmx_settledata_t   settled;        /* SETTLE data                        */
85     int                nblocks;        /* The number of SHAKE blocks         */
86     int               *sblock;         /* The SHAKE blocks                   */
87     int                sblock_nalloc;  /* The allocation size of sblock      */
88     real              *lagr;           /* -2 times the Lagrange multipliers for SHAKE */
89     int                lagr_nalloc;    /* The allocation size of lagr        */
90     int                maxwarn;        /* The maximum number of warnings     */
91     int                warncount_lincs;
92     int                warncount_settle;
93     gmx_edsam_t        ed;            /* The essential dynamics data        */
94
95     tensor            *vir_r_m_dr_th; /* Thread local working data          */
96     int               *settle_error;  /* Thread local working data          */
97
98     const gmx_mtop_t  *warn_mtop;     /* Only used for printing warnings    */
99 } t_gmx_constr;
100
101 typedef struct {
102     int iatom[3];
103     int blocknr;
104 } t_sortblock;
105
106 static int pcomp(const void *p1, const void *p2)
107 {
108     int          db;
109     int          min1, min2, max1, max2;
110     t_sortblock *a1 = (t_sortblock *)p1;
111     t_sortblock *a2 = (t_sortblock *)p2;
112
113     db = a1->blocknr-a2->blocknr;
114
115     if (db != 0)
116     {
117         return db;
118     }
119
120     min1 = std::min(a1->iatom[1], a1->iatom[2]);
121     max1 = std::max(a1->iatom[1], a1->iatom[2]);
122     min2 = std::min(a2->iatom[1], a2->iatom[2]);
123     max2 = std::max(a2->iatom[1], a2->iatom[2]);
124
125     if (min1 == min2)
126     {
127         return max1-max2;
128     }
129     else
130     {
131         return min1-min2;
132     }
133 }
134
135 int n_flexible_constraints(struct gmx_constr *constr)
136 {
137     int nflexcon;
138
139     if (constr)
140     {
141         nflexcon = constr->nflexcon;
142     }
143     else
144     {
145         nflexcon = 0;
146     }
147
148     return nflexcon;
149 }
150
151 static void clear_constraint_quantity_nonlocal(gmx_domdec_t *dd, rvec *q)
152 {
153     int nonlocal_at_start, nonlocal_at_end, at;
154
155     dd_get_constraint_range(dd, &nonlocal_at_start, &nonlocal_at_end);
156
157     for (at = nonlocal_at_start; at < nonlocal_at_end; at++)
158     {
159         clear_rvec(q[at]);
160     }
161 }
162
163 void too_many_constraint_warnings(int eConstrAlg, int warncount)
164 {
165     gmx_fatal(FARGS,
166               "Too many %s warnings (%d)\n"
167               "If you know what you are doing you can %s"
168               "set the environment variable GMX_MAXCONSTRWARN to -1,\n"
169               "but normally it is better to fix the problem",
170               (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE", warncount,
171               (eConstrAlg == econtLINCS) ?
172               "adjust the lincs warning threshold in your mdp file\nor " : "\n");
173 }
174
175 static void write_constr_pdb(const char *fn, const char *title,
176                              const gmx_mtop_t *mtop,
177                              int start, int homenr, t_commrec *cr,
178                              rvec x[], matrix box)
179 {
180     char          fname[STRLEN];
181     FILE         *out;
182     int           dd_ac0 = 0, dd_ac1 = 0, i, ii, resnr;
183     gmx_domdec_t *dd;
184     char         *anm, *resnm;
185
186     dd = NULL;
187     if (DOMAINDECOMP(cr))
188     {
189         dd = cr->dd;
190         dd_get_constraint_range(dd, &dd_ac0, &dd_ac1);
191         start  = 0;
192         homenr = dd_ac1;
193     }
194
195     if (PAR(cr))
196     {
197         sprintf(fname, "%s_n%d.pdb", fn, cr->sim_nodeid);
198     }
199     else
200     {
201         sprintf(fname, "%s.pdb", fn);
202     }
203
204     out = gmx_fio_fopen(fname, "w");
205
206     fprintf(out, "TITLE     %s\n", title);
207     gmx_write_pdb_box(out, -1, box);
208     for (i = start; i < start+homenr; i++)
209     {
210         if (dd != NULL)
211         {
212             if (i >= dd->nat_home && i < dd_ac0)
213             {
214                 continue;
215             }
216             ii = dd->gatindex[i];
217         }
218         else
219         {
220             ii = i;
221         }
222         gmx_mtop_atominfo_global(mtop, ii, &anm, &resnr, &resnm);
223         gmx_fprintf_pdb_atomline(out, epdbATOM, ii+1, anm, ' ', resnm, ' ', resnr, ' ',
224                                  10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, 0.0, "");
225     }
226     fprintf(out, "TER\n");
227
228     gmx_fio_fclose(out);
229 }
230
231 static void dump_confs(FILE *fplog, gmx_int64_t step, const gmx_mtop_t *mtop,
232                        int start, int homenr, t_commrec *cr,
233                        rvec x[], rvec xprime[], matrix box)
234 {
235     char  buf[256], buf2[22];
236
237     char *env = getenv("GMX_SUPPRESS_DUMP");
238     if (env)
239     {
240         return;
241     }
242
243     sprintf(buf, "step%sb", gmx_step_str(step, buf2));
244     write_constr_pdb(buf, "initial coordinates",
245                      mtop, start, homenr, cr, x, box);
246     sprintf(buf, "step%sc", gmx_step_str(step, buf2));
247     write_constr_pdb(buf, "coordinates after constraining",
248                      mtop, start, homenr, cr, xprime, box);
249     if (fplog)
250     {
251         fprintf(fplog, "Wrote pdb files with previous and current coordinates\n");
252     }
253     fprintf(stderr, "Wrote pdb files with previous and current coordinates\n");
254 }
255
256 static void pr_sortblock(FILE *fp, const char *title, int nsb, t_sortblock sb[])
257 {
258     int i;
259
260     fprintf(fp, "%s\n", title);
261     for (i = 0; (i < nsb); i++)
262     {
263         fprintf(fp, "i: %5d, iatom: (%5d %5d %5d), blocknr: %5d\n",
264                 i, sb[i].iatom[0], sb[i].iatom[1], sb[i].iatom[2],
265                 sb[i].blocknr);
266     }
267 }
268
269 gmx_bool constrain(FILE *fplog, gmx_bool bLog, gmx_bool bEner,
270                    struct gmx_constr *constr,
271                    t_idef *idef, t_inputrec *ir,
272                    t_commrec *cr,
273                    gmx_int64_t step, int delta_step,
274                    real step_scaling,
275                    t_mdatoms *md,
276                    rvec *x, rvec *xprime, rvec *min_proj,
277                    gmx_bool bMolPBC, matrix box,
278                    real lambda, real *dvdlambda,
279                    rvec *v, tensor *vir,
280                    t_nrnb *nrnb, int econq)
281 {
282     gmx_bool    bOK, bDump;
283     int         start, homenr;
284     int         i, j;
285     int         settle_error;
286     tensor      vir_r_m_dr;
287     real        scaled_delta_t;
288     real        invdt, vir_fac = 0, t;
289     t_ilist    *settle;
290     int         nsettle;
291     t_pbc       pbc, *pbc_null;
292     char        buf[22];
293     int         nth, th;
294
295     if (econq == econqForceDispl && !EI_ENERGY_MINIMIZATION(ir->eI))
296     {
297         gmx_incons("constrain called for forces displacements while not doing energy minimization, can not do this while the LINCS and SETTLE constraint connection matrices are mass weighted");
298     }
299
300     bOK   = TRUE;
301     bDump = FALSE;
302
303     start  = 0;
304     homenr = md->homenr;
305
306     scaled_delta_t = step_scaling * ir->delta_t;
307
308     /* Prepare time step for use in constraint implementations, and
309        avoid generating inf when ir->delta_t = 0. */
310     if (ir->delta_t == 0)
311     {
312         invdt = 0.0;
313     }
314     else
315     {
316         invdt = 1.0/scaled_delta_t;
317     }
318
319     if (ir->efep != efepNO && EI_DYNAMICS(ir->eI))
320     {
321         /* Set the constraint lengths for the step at which this configuration
322          * is meant to be. The invmasses should not be changed.
323          */
324         lambda += delta_step*ir->fepvals->delta_lambda;
325     }
326
327     if (vir != NULL)
328     {
329         clear_mat(vir_r_m_dr);
330     }
331
332     where();
333
334     settle  = &idef->il[F_SETTLE];
335     nsettle = settle->nr/(1+NRAL(F_SETTLE));
336
337     if (nsettle > 0)
338     {
339         nth = gmx_omp_nthreads_get(emntSETTLE);
340     }
341     else
342     {
343         nth = 1;
344     }
345
346     if (nth > 1 && constr->vir_r_m_dr_th == NULL)
347     {
348         snew(constr->vir_r_m_dr_th, nth);
349         snew(constr->settle_error, nth);
350     }
351
352     settle_error = -1;
353
354     /* We do not need full pbc when constraints do not cross charge groups,
355      * i.e. when dd->constraint_comm==NULL.
356      * Note that PBC for constraints is different from PBC for bondeds.
357      * For constraints there is both forward and backward communication.
358      */
359     if (ir->ePBC != epbcNONE &&
360         (cr->dd || bMolPBC) && !(cr->dd && cr->dd->constraint_comm == NULL))
361     {
362         /* With pbc=screw the screw has been changed to a shift
363          * by the constraint coordinate communication routine,
364          * so that here we can use normal pbc.
365          */
366         pbc_null = set_pbc_dd(&pbc, ir->ePBC,
367                               DOMAINDECOMP(cr) ? cr->dd->nc : nullptr,
368                               FALSE, box);
369     }
370     else
371     {
372         pbc_null = NULL;
373     }
374
375     /* Communicate the coordinates required for the non-local constraints
376      * for LINCS and/or SETTLE.
377      */
378     if (cr->dd)
379     {
380         dd_move_x_constraints(cr->dd, box, x, xprime, econq == econqCoord);
381
382         if (v != NULL)
383         {
384             /* We need to initialize the non-local components of v.
385              * We never actually use these values, but we do increment them,
386              * so we should avoid uninitialized variables and overflows.
387              */
388             clear_constraint_quantity_nonlocal(cr->dd, v);
389         }
390     }
391
392     if (constr->lincsd != NULL)
393     {
394         bOK = constrain_lincs(fplog, bLog, bEner, ir, step, constr->lincsd, md, cr,
395                               x, xprime, min_proj,
396                               box, pbc_null, lambda, dvdlambda,
397                               invdt, v, vir != NULL, vir_r_m_dr,
398                               econq, nrnb,
399                               constr->maxwarn, &constr->warncount_lincs);
400         if (!bOK && constr->maxwarn >= 0)
401         {
402             if (fplog != NULL)
403             {
404                 fprintf(fplog, "Constraint error in algorithm %s at step %s\n",
405                         econstr_names[econtLINCS], gmx_step_str(step, buf));
406             }
407             bDump = TRUE;
408         }
409     }
410
411     if (constr->nblocks > 0)
412     {
413         switch (econq)
414         {
415             case (econqCoord):
416                 bOK = bshakef(fplog, constr->shaked,
417                               md->invmass, constr->nblocks, constr->sblock,
418                               idef, ir, x, xprime, nrnb,
419                               constr->lagr, lambda, dvdlambda,
420                               invdt, v, vir != NULL, vir_r_m_dr,
421                               constr->maxwarn >= 0, econq);
422                 break;
423             case (econqVeloc):
424                 bOK = bshakef(fplog, constr->shaked,
425                               md->invmass, constr->nblocks, constr->sblock,
426                               idef, ir, x, min_proj, nrnb,
427                               constr->lagr, lambda, dvdlambda,
428                               invdt, NULL, vir != NULL, vir_r_m_dr,
429                               constr->maxwarn >= 0, econq);
430                 break;
431             default:
432                 gmx_fatal(FARGS, "Internal error, SHAKE called for constraining something else than coordinates");
433                 break;
434         }
435
436         if (!bOK && constr->maxwarn >= 0)
437         {
438             if (fplog != NULL)
439             {
440                 fprintf(fplog, "Constraint error in algorithm %s at step %s\n",
441                         econstr_names[econtSHAKE], gmx_step_str(step, buf));
442             }
443             bDump = TRUE;
444         }
445     }
446
447     if (nsettle > 0)
448     {
449         int calcvir_atom_end;
450
451         if (vir == NULL)
452         {
453             calcvir_atom_end = 0;
454         }
455         else
456         {
457             calcvir_atom_end = md->homenr;
458         }
459
460         switch (econq)
461         {
462             case econqCoord:
463 #pragma omp parallel for num_threads(nth) schedule(static)
464                 for (th = 0; th < nth; th++)
465                 {
466                     try
467                     {
468                         int start_th, end_th;
469
470                         if (th > 0)
471                         {
472                             clear_mat(constr->vir_r_m_dr_th[th]);
473
474                             constr->settle_error[th] = -1;
475                         }
476
477                         start_th = (nsettle* th   )/nth;
478                         end_th   = (nsettle*(th+1))/nth;
479                         if (start_th >= 0 && end_th - start_th > 0)
480                         {
481                             csettle(constr->settled,
482                                     end_th-start_th,
483                                     settle->iatoms+start_th*(1+NRAL(F_SETTLE)),
484                                     pbc_null,
485                                     x[0], xprime[0],
486                                     invdt, v ? v[0] : NULL, calcvir_atom_end,
487                                     th == 0 ? vir_r_m_dr : constr->vir_r_m_dr_th[th],
488                                     th == 0 ? &settle_error : &constr->settle_error[th]);
489                         }
490                     }
491                     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
492                 }
493                 inc_nrnb(nrnb, eNR_SETTLE, nsettle);
494                 if (v != NULL)
495                 {
496                     inc_nrnb(nrnb, eNR_CONSTR_V, nsettle*3);
497                 }
498                 if (vir != NULL)
499                 {
500                     inc_nrnb(nrnb, eNR_CONSTR_VIR, nsettle*3);
501                 }
502                 break;
503             case econqVeloc:
504             case econqDeriv:
505             case econqForce:
506             case econqForceDispl:
507 #pragma omp parallel for num_threads(nth) schedule(static)
508                 for (th = 0; th < nth; th++)
509                 {
510                     try
511                     {
512                         int start_th, end_th;
513
514                         if (th > 0)
515                         {
516                             clear_mat(constr->vir_r_m_dr_th[th]);
517                         }
518
519                         start_th = (nsettle* th   )/nth;
520                         end_th   = (nsettle*(th+1))/nth;
521
522                         if (start_th >= 0 && end_th - start_th > 0)
523                         {
524                             settle_proj(constr->settled, econq,
525                                         end_th-start_th,
526                                         settle->iatoms+start_th*(1+NRAL(F_SETTLE)),
527                                         pbc_null,
528                                         x,
529                                         xprime, min_proj, calcvir_atom_end,
530                                         th == 0 ? vir_r_m_dr : constr->vir_r_m_dr_th[th]);
531                         }
532                     }
533                     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
534                 }
535                 /* This is an overestimate */
536                 inc_nrnb(nrnb, eNR_SETTLE, nsettle);
537                 break;
538             case econqDeriv_FlexCon:
539                 /* Nothing to do, since the are no flexible constraints in settles */
540                 break;
541             default:
542                 gmx_incons("Unknown constraint quantity for settle");
543         }
544     }
545
546     if (settle->nr > 0)
547     {
548         if (vir != NULL)
549         {
550             /* Reduce the virial contributions over the threads */
551             for (i = 1; i < nth; i++)
552             {
553                 m_add(vir_r_m_dr, constr->vir_r_m_dr_th[i], vir_r_m_dr);
554             }
555         }
556
557         if (econq == econqCoord)
558         {
559             for (i = 1; i < nth; i++)
560             {
561                 settle_error = std::max(settle_error, constr->settle_error[i]);
562             }
563
564             if (settle_error >= 0)
565             {
566                 dump_confs(fplog, step, constr->warn_mtop, start, homenr, cr, x, xprime, box);
567
568                 gmx_fatal(FARGS,
569                           "\nstep " "%" GMX_PRId64 ": Water molecule starting at atom %d can not be "
570                           "settled.\nCheck for bad contacts and/or reduce the timestep if appropriate.\n",
571                           step, ddglatnr(cr->dd, settle->iatoms[settle_error*(1+NRAL(F_SETTLE))+1]));
572             }
573         }
574     }
575
576     if (vir != NULL)
577     {
578         /* The normal uses of constrain() pass step_scaling = 1.0.
579          * The call to constrain() for SD1 that passes step_scaling =
580          * 0.5 also passes vir = NULL, so cannot reach this
581          * assertion. This assertion should remain until someone knows
582          * that this path works for their intended purpose, and then
583          * they can use scaled_delta_t instead of ir->delta_t
584          * below. */
585         assert(gmx_within_tol(step_scaling, 1.0, GMX_REAL_EPS));
586         switch (econq)
587         {
588             case econqCoord:
589                 vir_fac = 0.5/(ir->delta_t*ir->delta_t);
590                 break;
591             case econqVeloc:
592                 vir_fac = 0.5/ir->delta_t;
593                 break;
594             case econqForce:
595             case econqForceDispl:
596                 vir_fac = 0.5;
597                 break;
598             default:
599                 gmx_incons("Unsupported constraint quantity for virial");
600         }
601
602         if (EI_VV(ir->eI))
603         {
604             vir_fac *= 2;  /* only constraining over half the distance here */
605         }
606         for (i = 0; i < DIM; i++)
607         {
608             for (j = 0; j < DIM; j++)
609             {
610                 (*vir)[i][j] = vir_fac*vir_r_m_dr[i][j];
611             }
612         }
613     }
614
615     if (bDump)
616     {
617         dump_confs(fplog, step, constr->warn_mtop, start, homenr, cr, x, xprime, box);
618     }
619
620     if (econq == econqCoord)
621     {
622         if (ir->bPull && pull_have_constraint(ir->pull_work))
623         {
624             if (EI_DYNAMICS(ir->eI))
625             {
626                 t = ir->init_t + (step + delta_step)*ir->delta_t;
627             }
628             else
629             {
630                 t = ir->init_t;
631             }
632             set_pbc(&pbc, ir->ePBC, box);
633             pull_constraint(ir->pull_work, md, &pbc, cr, ir->delta_t, t, x, xprime, v, *vir);
634         }
635         if (constr->ed && delta_step > 0)
636         {
637             /* apply the essential dynamcs constraints here */
638             do_edsam(ir, step, cr, xprime, v, box, constr->ed);
639         }
640     }
641
642     return bOK;
643 }
644
645 real *constr_rmsd_data(struct gmx_constr *constr)
646 {
647     if (constr->lincsd)
648     {
649         return lincs_rmsd_data(constr->lincsd);
650     }
651     else
652     {
653         return NULL;
654     }
655 }
656
657 real constr_rmsd(struct gmx_constr *constr)
658 {
659     if (constr->lincsd)
660     {
661         return lincs_rmsd(constr->lincsd);
662     }
663     else
664     {
665         return 0;
666     }
667 }
668
669 static void make_shake_sblock_serial(struct gmx_constr *constr,
670                                      t_idef *idef, const t_mdatoms *md)
671 {
672     int          i, j, m, ncons;
673     int          bstart, bnr;
674     t_blocka     sblocks;
675     t_sortblock *sb;
676     t_iatom     *iatom;
677     int         *inv_sblock;
678
679     /* Since we are processing the local topology,
680      * the F_CONSTRNC ilist has been concatenated to the F_CONSTR ilist.
681      */
682     ncons = idef->il[F_CONSTR].nr/3;
683
684     init_blocka(&sblocks);
685     gen_sblocks(NULL, 0, md->homenr, idef, &sblocks, FALSE);
686
687     /*
688        bstart=(idef->nodeid > 0) ? blocks->multinr[idef->nodeid-1] : 0;
689        nblocks=blocks->multinr[idef->nodeid] - bstart;
690      */
691     bstart          = 0;
692     constr->nblocks = sblocks.nr;
693     if (debug)
694     {
695         fprintf(debug, "ncons: %d, bstart: %d, nblocks: %d\n",
696                 ncons, bstart, constr->nblocks);
697     }
698
699     /* Calculate block number for each atom */
700     inv_sblock = make_invblocka(&sblocks, md->nr);
701
702     done_blocka(&sblocks);
703
704     /* Store the block number in temp array and
705      * sort the constraints in order of the sblock number
706      * and the atom numbers, really sorting a segment of the array!
707      */
708 #ifdef DEBUGIDEF
709     pr_idef(fplog, 0, "Before Sort", idef);
710 #endif
711     iatom = idef->il[F_CONSTR].iatoms;
712     snew(sb, ncons);
713     for (i = 0; (i < ncons); i++, iatom += 3)
714     {
715         for (m = 0; (m < 3); m++)
716         {
717             sb[i].iatom[m] = iatom[m];
718         }
719         sb[i].blocknr = inv_sblock[iatom[1]];
720     }
721
722     /* Now sort the blocks */
723     if (debug)
724     {
725         pr_sortblock(debug, "Before sorting", ncons, sb);
726         fprintf(debug, "Going to sort constraints\n");
727     }
728
729     qsort(sb, ncons, (size_t)sizeof(*sb), pcomp);
730
731     if (debug)
732     {
733         pr_sortblock(debug, "After sorting", ncons, sb);
734     }
735
736     iatom = idef->il[F_CONSTR].iatoms;
737     for (i = 0; (i < ncons); i++, iatom += 3)
738     {
739         for (m = 0; (m < 3); m++)
740         {
741             iatom[m] = sb[i].iatom[m];
742         }
743     }
744 #ifdef DEBUGIDEF
745     pr_idef(fplog, 0, "After Sort", idef);
746 #endif
747
748     j = 0;
749     snew(constr->sblock, constr->nblocks+1);
750     bnr = -2;
751     for (i = 0; (i < ncons); i++)
752     {
753         if (sb[i].blocknr != bnr)
754         {
755             bnr                 = sb[i].blocknr;
756             constr->sblock[j++] = 3*i;
757         }
758     }
759     /* Last block... */
760     constr->sblock[j++] = 3*ncons;
761
762     if (j != (constr->nblocks+1))
763     {
764         fprintf(stderr, "bstart: %d\n", bstart);
765         fprintf(stderr, "j: %d, nblocks: %d, ncons: %d\n",
766                 j, constr->nblocks, ncons);
767         for (i = 0; (i < ncons); i++)
768         {
769             fprintf(stderr, "i: %5d  sb[i].blocknr: %5d\n", i, sb[i].blocknr);
770         }
771         for (j = 0; (j <= constr->nblocks); j++)
772         {
773             fprintf(stderr, "sblock[%3d]=%5d\n", j, (int)constr->sblock[j]);
774         }
775         gmx_fatal(FARGS, "DEATH HORROR: "
776                   "sblocks does not match idef->il[F_CONSTR]");
777     }
778     sfree(sb);
779     sfree(inv_sblock);
780 }
781
782 static void make_shake_sblock_dd(struct gmx_constr *constr,
783                                  const t_ilist *ilcon, const t_block *cgs,
784                                  const gmx_domdec_t *dd)
785 {
786     int      ncons, c, cg;
787     t_iatom *iatom;
788
789     if (dd->ncg_home+1 > constr->sblock_nalloc)
790     {
791         constr->sblock_nalloc = over_alloc_dd(dd->ncg_home+1);
792         srenew(constr->sblock, constr->sblock_nalloc);
793     }
794
795     ncons           = ilcon->nr/3;
796     iatom           = ilcon->iatoms;
797     constr->nblocks = 0;
798     cg              = 0;
799     for (c = 0; c < ncons; c++)
800     {
801         if (c == 0 || iatom[1] >= cgs->index[cg+1])
802         {
803             constr->sblock[constr->nblocks++] = 3*c;
804             while (iatom[1] >= cgs->index[cg+1])
805             {
806                 cg++;
807             }
808         }
809         iatom += 3;
810     }
811     constr->sblock[constr->nblocks] = 3*ncons;
812 }
813
814 t_blocka make_at2con(int start, int natoms,
815                      const t_ilist *ilist, const t_iparams *iparams,
816                      gmx_bool bDynamics, int *nflexiblecons)
817 {
818     int      *count, ncon, con, con_tot, nflexcon, ftype, i, a;
819     t_iatom  *ia;
820     t_blocka  at2con;
821     gmx_bool  bFlexCon;
822
823     snew(count, natoms);
824     nflexcon = 0;
825     for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
826     {
827         ncon = ilist[ftype].nr/3;
828         ia   = ilist[ftype].iatoms;
829         for (con = 0; con < ncon; con++)
830         {
831             bFlexCon = (iparams[ia[0]].constr.dA == 0 &&
832                         iparams[ia[0]].constr.dB == 0);
833             if (bFlexCon)
834             {
835                 nflexcon++;
836             }
837             if (bDynamics || !bFlexCon)
838             {
839                 for (i = 1; i < 3; i++)
840                 {
841                     a = ia[i] - start;
842                     count[a]++;
843                 }
844             }
845             ia += 3;
846         }
847     }
848     *nflexiblecons = nflexcon;
849
850     at2con.nr           = natoms;
851     at2con.nalloc_index = at2con.nr+1;
852     snew(at2con.index, at2con.nalloc_index);
853     at2con.index[0] = 0;
854     for (a = 0; a < natoms; a++)
855     {
856         at2con.index[a+1] = at2con.index[a] + count[a];
857         count[a]          = 0;
858     }
859     at2con.nra      = at2con.index[natoms];
860     at2con.nalloc_a = at2con.nra;
861     snew(at2con.a, at2con.nalloc_a);
862
863     /* The F_CONSTRNC constraints have constraint numbers
864      * that continue after the last F_CONSTR constraint.
865      */
866     con_tot = 0;
867     for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
868     {
869         ncon = ilist[ftype].nr/3;
870         ia   = ilist[ftype].iatoms;
871         for (con = 0; con < ncon; con++)
872         {
873             bFlexCon = (iparams[ia[0]].constr.dA == 0 &&
874                         iparams[ia[0]].constr.dB == 0);
875             if (bDynamics || !bFlexCon)
876             {
877                 for (i = 1; i < 3; i++)
878                 {
879                     a = ia[i] - start;
880                     at2con.a[at2con.index[a]+count[a]++] = con_tot;
881                 }
882             }
883             con_tot++;
884             ia += 3;
885         }
886     }
887
888     sfree(count);
889
890     return at2con;
891 }
892
893 static int *make_at2settle(int natoms, const t_ilist *ilist)
894 {
895     int *at2s;
896     int  a, stride, s;
897
898     snew(at2s, natoms);
899     /* Set all to no settle */
900     for (a = 0; a < natoms; a++)
901     {
902         at2s[a] = -1;
903     }
904
905     stride = 1 + NRAL(F_SETTLE);
906
907     for (s = 0; s < ilist->nr; s += stride)
908     {
909         at2s[ilist->iatoms[s+1]] = s/stride;
910         at2s[ilist->iatoms[s+2]] = s/stride;
911         at2s[ilist->iatoms[s+3]] = s/stride;
912     }
913
914     return at2s;
915 }
916
917 void set_constraints(struct gmx_constr *constr,
918                      gmx_localtop_t *top, const t_inputrec *ir,
919                      const t_mdatoms *md, t_commrec *cr)
920 {
921     t_idef        *idef;
922     int            ncons;
923     const t_ilist *settle;
924     int            iO, iH;
925
926     idef = &top->idef;
927
928     if (constr->ncon_tot > 0)
929     {
930         /* We are using the local topology,
931          * so there are only F_CONSTR constraints.
932          */
933         ncons = idef->il[F_CONSTR].nr/3;
934
935         /* With DD we might also need to call LINCS with ncons=0 for
936          * communicating coordinates to other nodes that do have constraints.
937          */
938         if (ir->eConstrAlg == econtLINCS)
939         {
940             set_lincs(idef, md, EI_DYNAMICS(ir->eI), cr, constr->lincsd);
941         }
942         if (ir->eConstrAlg == econtSHAKE)
943         {
944             if (cr->dd)
945             {
946                 make_shake_sblock_dd(constr, &idef->il[F_CONSTR], &top->cgs, cr->dd);
947             }
948             else
949             {
950                 make_shake_sblock_serial(constr, idef, md);
951             }
952             if (ncons > constr->lagr_nalloc)
953             {
954                 constr->lagr_nalloc = over_alloc_dd(ncons);
955                 srenew(constr->lagr, constr->lagr_nalloc);
956             }
957         }
958     }
959
960     if (idef->il[F_SETTLE].nr > 0 && constr->settled == NULL)
961     {
962         settle          = &idef->il[F_SETTLE];
963         iO              = settle->iatoms[1];
964         iH              = settle->iatoms[2];
965         constr->settled =
966             settle_init(md->massT[iO], md->massT[iH],
967                         md->invmass[iO], md->invmass[iH],
968                         idef->iparams[settle->iatoms[0]].settle.doh,
969                         idef->iparams[settle->iatoms[0]].settle.dhh);
970     }
971
972     /* Make a selection of the local atoms for essential dynamics */
973     if (constr->ed && cr->dd)
974     {
975         dd_make_local_ed_indices(cr->dd, constr->ed);
976     }
977 }
978
979 static void constr_recur(const t_blocka *at2con,
980                          const t_ilist *ilist, const t_iparams *iparams,
981                          gmx_bool bTopB,
982                          int at, int depth, int nc, int *path,
983                          real r0, real r1, real *r2max,
984                          int *count)
985 {
986     int      ncon1;
987     t_iatom *ia1, *ia2;
988     int      c, con, a1;
989     gmx_bool bUse;
990     t_iatom *ia;
991     real     len, rn0, rn1;
992
993     (*count)++;
994
995     ncon1 = ilist[F_CONSTR].nr/3;
996     ia1   = ilist[F_CONSTR].iatoms;
997     ia2   = ilist[F_CONSTRNC].iatoms;
998
999     /* Loop over all constraints connected to this atom */
1000     for (c = at2con->index[at]; c < at2con->index[at+1]; c++)
1001     {
1002         con = at2con->a[c];
1003         /* Do not walk over already used constraints */
1004         bUse = TRUE;
1005         for (a1 = 0; a1 < depth; a1++)
1006         {
1007             if (con == path[a1])
1008             {
1009                 bUse = FALSE;
1010             }
1011         }
1012         if (bUse)
1013         {
1014             ia = constr_iatomptr(ncon1, ia1, ia2, con);
1015             /* Flexible constraints currently have length 0, which is incorrect */
1016             if (!bTopB)
1017             {
1018                 len = iparams[ia[0]].constr.dA;
1019             }
1020             else
1021             {
1022                 len = iparams[ia[0]].constr.dB;
1023             }
1024             /* In the worst case the bond directions alternate */
1025             if (nc % 2 == 0)
1026             {
1027                 rn0 = r0 + len;
1028                 rn1 = r1;
1029             }
1030             else
1031             {
1032                 rn0 = r0;
1033                 rn1 = r1 + len;
1034             }
1035             /* Assume angles of 120 degrees between all bonds */
1036             if (rn0*rn0 + rn1*rn1 + rn0*rn1 > *r2max)
1037             {
1038                 *r2max = rn0*rn0 + rn1*rn1 + r0*rn1;
1039                 if (debug)
1040                 {
1041                     fprintf(debug, "Found longer constraint distance: r0 %5.3f r1 %5.3f rmax %5.3f\n", rn0, rn1, sqrt(*r2max));
1042                     for (a1 = 0; a1 < depth; a1++)
1043                     {
1044                         fprintf(debug, " %d %5.3f",
1045                                 path[a1],
1046                                 iparams[constr_iatomptr(ncon1, ia1, ia2, con)[0]].constr.dA);
1047                     }
1048                     fprintf(debug, " %d %5.3f\n", con, len);
1049                 }
1050             }
1051             /* Limit the number of recursions to 1000*nc,
1052              * so a call does not take more than a second,
1053              * even for highly connected systems.
1054              */
1055             if (depth + 1 < nc && *count < 1000*nc)
1056             {
1057                 if (ia[1] == at)
1058                 {
1059                     a1 = ia[2];
1060                 }
1061                 else
1062                 {
1063                     a1 = ia[1];
1064                 }
1065                 /* Recursion */
1066                 path[depth] = con;
1067                 constr_recur(at2con, ilist, iparams,
1068                              bTopB, a1, depth+1, nc, path, rn0, rn1, r2max, count);
1069                 path[depth] = -1;
1070             }
1071         }
1072     }
1073 }
1074
1075 static real constr_r_max_moltype(const gmx_moltype_t *molt,
1076                                  const t_iparams     *iparams,
1077                                  const t_inputrec    *ir)
1078 {
1079     int      natoms, nflexcon, *path, at, count;
1080
1081     t_blocka at2con;
1082     real     r0, r1, r2maxA, r2maxB, rmax, lam0, lam1;
1083
1084     if (molt->ilist[F_CONSTR].nr   == 0 &&
1085         molt->ilist[F_CONSTRNC].nr == 0)
1086     {
1087         return 0;
1088     }
1089
1090     natoms = molt->atoms.nr;
1091
1092     at2con = make_at2con(0, natoms, molt->ilist, iparams,
1093                          EI_DYNAMICS(ir->eI), &nflexcon);
1094     snew(path, 1+ir->nProjOrder);
1095     for (at = 0; at < 1+ir->nProjOrder; at++)
1096     {
1097         path[at] = -1;
1098     }
1099
1100     r2maxA = 0;
1101     for (at = 0; at < natoms; at++)
1102     {
1103         r0 = 0;
1104         r1 = 0;
1105
1106         count = 0;
1107         constr_recur(&at2con, molt->ilist, iparams,
1108                      FALSE, at, 0, 1+ir->nProjOrder, path, r0, r1, &r2maxA, &count);
1109     }
1110     if (ir->efep == efepNO)
1111     {
1112         rmax = sqrt(r2maxA);
1113     }
1114     else
1115     {
1116         r2maxB = 0;
1117         for (at = 0; at < natoms; at++)
1118         {
1119             r0    = 0;
1120             r1    = 0;
1121             count = 0;
1122             constr_recur(&at2con, molt->ilist, iparams,
1123                          TRUE, at, 0, 1+ir->nProjOrder, path, r0, r1, &r2maxB, &count);
1124         }
1125         lam0 = ir->fepvals->init_lambda;
1126         if (EI_DYNAMICS(ir->eI))
1127         {
1128             lam0 += ir->init_step*ir->fepvals->delta_lambda;
1129         }
1130         rmax = (1 - lam0)*sqrt(r2maxA) + lam0*sqrt(r2maxB);
1131         if (EI_DYNAMICS(ir->eI))
1132         {
1133             lam1 = ir->fepvals->init_lambda + (ir->init_step + ir->nsteps)*ir->fepvals->delta_lambda;
1134             rmax = std::max(rmax, (1 - lam1)*std::sqrt(r2maxA) + lam1*std::sqrt(r2maxB));
1135         }
1136     }
1137
1138     done_blocka(&at2con);
1139     sfree(path);
1140
1141     return rmax;
1142 }
1143
1144 real constr_r_max(FILE *fplog, const gmx_mtop_t *mtop, const t_inputrec *ir)
1145 {
1146     int  mt;
1147     real rmax;
1148
1149     rmax = 0;
1150     for (mt = 0; mt < mtop->nmoltype; mt++)
1151     {
1152         rmax = std::max(rmax,
1153                         constr_r_max_moltype(&mtop->moltype[mt],
1154                                              mtop->ffparams.iparams, ir));
1155     }
1156
1157     if (fplog)
1158     {
1159         fprintf(fplog, "Maximum distance for %d constraints, at 120 deg. angles, all-trans: %.3f nm\n", 1+ir->nProjOrder, rmax);
1160     }
1161
1162     return rmax;
1163 }
1164
1165 gmx_constr_t init_constraints(FILE *fplog,
1166                               const gmx_mtop_t *mtop, const t_inputrec *ir,
1167                               gmx_edsam_t ed, t_state *state,
1168                               t_commrec *cr)
1169 {
1170     int                  ncon, nset, nmol, settle_type, i, mt, nflexcon;
1171     struct gmx_constr   *constr;
1172     char                *env;
1173     t_ilist             *ilist;
1174     gmx_mtop_ilistloop_t iloop;
1175
1176     ncon =
1177         gmx_mtop_ftype_count(mtop, F_CONSTR) +
1178         gmx_mtop_ftype_count(mtop, F_CONSTRNC);
1179     nset = gmx_mtop_ftype_count(mtop, F_SETTLE);
1180
1181     if (ncon+nset == 0 &&
1182         !(ir->bPull && pull_have_constraint(ir->pull_work)) &&
1183         ed == NULL)
1184     {
1185         return NULL;
1186     }
1187
1188     snew(constr, 1);
1189
1190     constr->ncon_tot = ncon;
1191     constr->nflexcon = 0;
1192     if (ncon > 0)
1193     {
1194         constr->n_at2con_mt = mtop->nmoltype;
1195         snew(constr->at2con_mt, constr->n_at2con_mt);
1196         for (mt = 0; mt < mtop->nmoltype; mt++)
1197         {
1198             constr->at2con_mt[mt] = make_at2con(0, mtop->moltype[mt].atoms.nr,
1199                                                 mtop->moltype[mt].ilist,
1200                                                 mtop->ffparams.iparams,
1201                                                 EI_DYNAMICS(ir->eI), &nflexcon);
1202             for (i = 0; i < mtop->nmolblock; i++)
1203             {
1204                 if (mtop->molblock[i].type == mt)
1205                 {
1206                     constr->nflexcon += mtop->molblock[i].nmol*nflexcon;
1207                 }
1208             }
1209         }
1210
1211         if (constr->nflexcon > 0)
1212         {
1213             if (fplog)
1214             {
1215                 fprintf(fplog, "There are %d flexible constraints\n",
1216                         constr->nflexcon);
1217                 if (ir->fc_stepsize == 0)
1218                 {
1219                     fprintf(fplog, "\n"
1220                             "WARNING: step size for flexible constraining = 0\n"
1221                             "         All flexible constraints will be rigid.\n"
1222                             "         Will try to keep all flexible constraints at their original length,\n"
1223                             "         but the lengths may exhibit some drift.\n\n");
1224                     constr->nflexcon = 0;
1225                 }
1226             }
1227             if (constr->nflexcon > 0)
1228             {
1229                 please_cite(fplog, "Hess2002");
1230             }
1231         }
1232
1233         if (ir->eConstrAlg == econtLINCS)
1234         {
1235             constr->lincsd = init_lincs(fplog, mtop,
1236                                         constr->nflexcon, constr->at2con_mt,
1237                                         DOMAINDECOMP(cr) && cr->dd->bInterCGcons,
1238                                         ir->nLincsIter, ir->nProjOrder);
1239         }
1240
1241         if (ir->eConstrAlg == econtSHAKE)
1242         {
1243             if (DOMAINDECOMP(cr) && cr->dd->bInterCGcons)
1244             {
1245                 gmx_fatal(FARGS, "SHAKE is not supported with domain decomposition and constraint that cross charge group boundaries, use LINCS");
1246             }
1247             if (constr->nflexcon)
1248             {
1249                 gmx_fatal(FARGS, "For this system also velocities and/or forces need to be constrained, this can not be done with SHAKE, you should select LINCS");
1250             }
1251             please_cite(fplog, "Ryckaert77a");
1252             if (ir->bShakeSOR)
1253             {
1254                 please_cite(fplog, "Barth95a");
1255             }
1256
1257             constr->shaked = shake_init();
1258         }
1259     }
1260
1261     if (nset > 0)
1262     {
1263         please_cite(fplog, "Miyamoto92a");
1264
1265         constr->bInterCGsettles = inter_charge_group_settles(mtop);
1266
1267         /* Check that we have only one settle type */
1268         settle_type = -1;
1269         iloop       = gmx_mtop_ilistloop_init(mtop);
1270         while (gmx_mtop_ilistloop_next(iloop, &ilist, &nmol))
1271         {
1272             for (i = 0; i < ilist[F_SETTLE].nr; i += 4)
1273             {
1274                 if (settle_type == -1)
1275                 {
1276                     settle_type = ilist[F_SETTLE].iatoms[i];
1277                 }
1278                 else if (ilist[F_SETTLE].iatoms[i] != settle_type)
1279                 {
1280                     gmx_fatal(FARGS,
1281                               "The [molecules] section of your topology specifies more than one block of\n"
1282                               "a [moleculetype] with a [settles] block. Only one such is allowed. If you\n"
1283                               "are trying to partition your solvent into different *groups* (e.g. for\n"
1284                               "freezing, T-coupling, etc.) then you are using the wrong approach. Index\n"
1285                               "files specify groups. Otherwise, you may wish to change the least-used\n"
1286                               "block of molecules with SETTLE constraints into 3 normal constraints.");
1287                 }
1288             }
1289         }
1290
1291         constr->n_at2settle_mt = mtop->nmoltype;
1292         snew(constr->at2settle_mt, constr->n_at2settle_mt);
1293         for (mt = 0; mt < mtop->nmoltype; mt++)
1294         {
1295             constr->at2settle_mt[mt] =
1296                 make_at2settle(mtop->moltype[mt].atoms.nr,
1297                                &mtop->moltype[mt].ilist[F_SETTLE]);
1298         }
1299     }
1300
1301     if ((ncon + nset) > 0 && ir->epc == epcMTTK)
1302     {
1303         gmx_fatal(FARGS, "Constraints are not implemented with MTTK pressure control.");
1304     }
1305
1306     constr->maxwarn = 999;
1307     env             = getenv("GMX_MAXCONSTRWARN");
1308     if (env)
1309     {
1310         constr->maxwarn = 0;
1311         sscanf(env, "%8d", &constr->maxwarn);
1312         if (fplog)
1313         {
1314             fprintf(fplog,
1315                     "Setting the maximum number of constraint warnings to %d\n",
1316                     constr->maxwarn);
1317         }
1318         if (MASTER(cr))
1319         {
1320             fprintf(stderr,
1321                     "Setting the maximum number of constraint warnings to %d\n",
1322                     constr->maxwarn);
1323         }
1324     }
1325     if (constr->maxwarn < 0 && fplog)
1326     {
1327         fprintf(fplog, "maxwarn < 0, will not stop on constraint errors\n");
1328     }
1329     constr->warncount_lincs  = 0;
1330     constr->warncount_settle = 0;
1331
1332     /* Initialize the essential dynamics sampling.
1333      * Put the pointer to the ED struct in constr */
1334     constr->ed = ed;
1335     if (ed != NULL || state->edsamstate.nED > 0)
1336     {
1337         init_edsam(mtop, ir, cr, ed, state->x, state->box, &state->edsamstate);
1338     }
1339
1340     constr->warn_mtop = mtop;
1341
1342     return constr;
1343 }
1344
1345 const t_blocka *atom2constraints_moltype(gmx_constr_t constr)
1346 {
1347     return constr->at2con_mt;
1348 }
1349
1350 const int **atom2settle_moltype(gmx_constr_t constr)
1351 {
1352     return (const int **)constr->at2settle_mt;
1353 }
1354
1355
1356 gmx_bool inter_charge_group_constraints(const gmx_mtop_t *mtop)
1357 {
1358     const gmx_moltype_t *molt;
1359     const t_block       *cgs;
1360     const t_ilist       *il;
1361     int                  mb;
1362     int                 *at2cg, cg, a, ftype, i;
1363     gmx_bool             bInterCG;
1364
1365     bInterCG = FALSE;
1366     for (mb = 0; mb < mtop->nmolblock && !bInterCG; mb++)
1367     {
1368         molt = &mtop->moltype[mtop->molblock[mb].type];
1369
1370         if (molt->ilist[F_CONSTR].nr   > 0 ||
1371             molt->ilist[F_CONSTRNC].nr > 0 ||
1372             molt->ilist[F_SETTLE].nr > 0)
1373         {
1374             cgs  = &molt->cgs;
1375             snew(at2cg, molt->atoms.nr);
1376             for (cg = 0; cg < cgs->nr; cg++)
1377             {
1378                 for (a = cgs->index[cg]; a < cgs->index[cg+1]; a++)
1379                 {
1380                     at2cg[a] = cg;
1381                 }
1382             }
1383
1384             for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
1385             {
1386                 il = &molt->ilist[ftype];
1387                 for (i = 0; i < il->nr && !bInterCG; i += 1+NRAL(ftype))
1388                 {
1389                     if (at2cg[il->iatoms[i+1]] != at2cg[il->iatoms[i+2]])
1390                     {
1391                         bInterCG = TRUE;
1392                     }
1393                 }
1394             }
1395
1396             sfree(at2cg);
1397         }
1398     }
1399
1400     return bInterCG;
1401 }
1402
1403 gmx_bool inter_charge_group_settles(const gmx_mtop_t *mtop)
1404 {
1405     const gmx_moltype_t *molt;
1406     const t_block       *cgs;
1407     const t_ilist       *il;
1408     int                  mb;
1409     int                 *at2cg, cg, a, ftype, i;
1410     gmx_bool             bInterCG;
1411
1412     bInterCG = FALSE;
1413     for (mb = 0; mb < mtop->nmolblock && !bInterCG; mb++)
1414     {
1415         molt = &mtop->moltype[mtop->molblock[mb].type];
1416
1417         if (molt->ilist[F_SETTLE].nr > 0)
1418         {
1419             cgs  = &molt->cgs;
1420             snew(at2cg, molt->atoms.nr);
1421             for (cg = 0; cg < cgs->nr; cg++)
1422             {
1423                 for (a = cgs->index[cg]; a < cgs->index[cg+1]; a++)
1424                 {
1425                     at2cg[a] = cg;
1426                 }
1427             }
1428
1429             for (ftype = F_SETTLE; ftype <= F_SETTLE; ftype++)
1430             {
1431                 il = &molt->ilist[ftype];
1432                 for (i = 0; i < il->nr && !bInterCG; i += 1+NRAL(F_SETTLE))
1433                 {
1434                     if (at2cg[il->iatoms[i+1]] != at2cg[il->iatoms[i+2]] ||
1435                         at2cg[il->iatoms[i+1]] != at2cg[il->iatoms[i+3]])
1436                     {
1437                         bInterCG = TRUE;
1438                     }
1439                 }
1440             }
1441
1442             sfree(at2cg);
1443         }
1444     }
1445
1446     return bInterCG;
1447 }
1448
1449 /* helper functions for andersen temperature control, because the
1450  * gmx_constr construct is only defined in constr.c. Return the list
1451  * of blocks (get_sblock) and the number of blocks (get_nblocks).  */
1452
1453 extern int *get_sblock(struct gmx_constr *constr)
1454 {
1455     return constr->sblock;
1456 }
1457
1458 extern int get_nblocks(struct gmx_constr *constr)
1459 {
1460     return constr->nblocks;
1461 }