Merge branch release-2018 into release-2019
[alexxy/gromacs.git] / src / gromacs / gmxpreprocess / readir.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,2017,2018, 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 "readir.h"
40
41 #include <cctype>
42 #include <climits>
43 #include <cmath>
44 #include <cstdlib>
45
46 #include <algorithm>
47 #include <string>
48
49 #include "gromacs/awh/read-params.h"
50 #include "gromacs/fileio/readinp.h"
51 #include "gromacs/fileio/warninp.h"
52 #include "gromacs/gmxlib/chargegroup.h"
53 #include "gromacs/gmxlib/network.h"
54 #include "gromacs/gmxpreprocess/keyvaluetreemdpwriter.h"
55 #include "gromacs/gmxpreprocess/toputil.h"
56 #include "gromacs/math/functions.h"
57 #include "gromacs/math/units.h"
58 #include "gromacs/math/vec.h"
59 #include "gromacs/mdlib/calc_verletbuf.h"
60 #include "gromacs/mdrunutility/mdmodules.h"
61 #include "gromacs/mdtypes/inputrec.h"
62 #include "gromacs/mdtypes/md_enums.h"
63 #include "gromacs/mdtypes/pull-params.h"
64 #include "gromacs/options/options.h"
65 #include "gromacs/options/treesupport.h"
66 #include "gromacs/pbcutil/pbc.h"
67 #include "gromacs/topology/block.h"
68 #include "gromacs/topology/ifunc.h"
69 #include "gromacs/topology/index.h"
70 #include "gromacs/topology/mtop_util.h"
71 #include "gromacs/topology/symtab.h"
72 #include "gromacs/topology/topology.h"
73 #include "gromacs/utility/cstringutil.h"
74 #include "gromacs/utility/exceptions.h"
75 #include "gromacs/utility/fatalerror.h"
76 #include "gromacs/utility/filestream.h"
77 #include "gromacs/utility/gmxassert.h"
78 #include "gromacs/utility/ikeyvaluetreeerror.h"
79 #include "gromacs/utility/keyvaluetree.h"
80 #include "gromacs/utility/keyvaluetreebuilder.h"
81 #include "gromacs/utility/keyvaluetreetransform.h"
82 #include "gromacs/utility/smalloc.h"
83 #include "gromacs/utility/strconvert.h"
84 #include "gromacs/utility/stringcompare.h"
85 #include "gromacs/utility/stringutil.h"
86 #include "gromacs/utility/textwriter.h"
87
88 #define MAXPTR 254
89 #define NOGID  255
90
91 /* Resource parameters
92  * Do not change any of these until you read the instruction
93  * in readinp.h. Some cpp's do not take spaces after the backslash
94  * (like the c-shell), which will give you a very weird compiler
95  * message.
96  */
97
98 typedef struct t_inputrec_strings
99 {
100     char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN],
101          acc[STRLEN], accgrps[STRLEN], freeze[STRLEN], frdim[STRLEN],
102          energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], x_compressed_groups[STRLEN],
103          couple_moltype[STRLEN], orirefitgrp[STRLEN], egptable[STRLEN], egpexcl[STRLEN],
104          wall_atomtype[STRLEN], wall_density[STRLEN], deform[STRLEN], QMMM[STRLEN],
105          imd_grp[STRLEN];
106     char   fep_lambda[efptNR][STRLEN];
107     char   lambda_weights[STRLEN];
108     char **pull_grp;
109     char **rot_grp;
110     char   anneal[STRLEN], anneal_npoints[STRLEN],
111            anneal_time[STRLEN], anneal_temp[STRLEN];
112     char   QMmethod[STRLEN], QMbasis[STRLEN], QMcharge[STRLEN], QMmult[STRLEN],
113            bSH[STRLEN], CASorbitals[STRLEN], CASelectrons[STRLEN], SAon[STRLEN],
114            SAoff[STRLEN], SAsteps[STRLEN];
115
116 } gmx_inputrec_strings;
117
118 static gmx_inputrec_strings *is = nullptr;
119
120 void init_inputrec_strings()
121 {
122     if (is)
123     {
124         gmx_incons("Attempted to call init_inputrec_strings before calling done_inputrec_strings. Only one inputrec (i.e. .mdp file) can be parsed at a time.");
125     }
126     snew(is, 1);
127 }
128
129 void done_inputrec_strings()
130 {
131     sfree(is);
132     is = nullptr;
133 }
134
135
136 enum {
137     egrptpALL,         /* All particles have to be a member of a group.     */
138     egrptpALL_GENREST, /* A rest group with name is generated for particles *
139                         * that are not part of any group.                   */
140     egrptpPART,        /* As egrptpALL_GENREST, but no name is generated    *
141                         * for the rest group.                               */
142     egrptpONE          /* Merge all selected groups into one group,         *
143                         * make a rest group for the remaining particles.    */
144 };
145
146 static const char *constraints[eshNR+1]    = {
147     "none", "h-bonds", "all-bonds", "h-angles", "all-angles", nullptr
148 };
149
150 static const char *couple_lam[ecouplamNR+1]    = {
151     "vdw-q", "vdw", "q", "none", nullptr
152 };
153
154 static void GetSimTemps(int ntemps, t_simtemp *simtemp, double *temperature_lambdas)
155 {
156
157     int i;
158
159     for (i = 0; i < ntemps; i++)
160     {
161         /* simple linear scaling -- allows more control */
162         if (simtemp->eSimTempScale == esimtempLINEAR)
163         {
164             simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*temperature_lambdas[i];
165         }
166         else if (simtemp->eSimTempScale == esimtempGEOMETRIC)  /* should give roughly equal acceptance for constant heat capacity . . . */
167         {
168             simtemp->temperatures[i] = simtemp->simtemp_low * std::pow(simtemp->simtemp_high/simtemp->simtemp_low, static_cast<real>((1.0*i)/(ntemps-1)));
169         }
170         else if (simtemp->eSimTempScale == esimtempEXPONENTIAL)
171         {
172             simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*(std::expm1(temperature_lambdas[i])/std::expm1(1.0));
173         }
174         else
175         {
176             char errorstr[128];
177             sprintf(errorstr, "eSimTempScale=%d not defined", simtemp->eSimTempScale);
178             gmx_fatal(FARGS, "%s", errorstr);
179         }
180     }
181 }
182
183
184
185 static void _low_check(bool b, const char *s, warninp_t wi)
186 {
187     if (b)
188     {
189         warning_error(wi, s);
190     }
191 }
192
193 static void check_nst(const char *desc_nst, int nst,
194                       const char *desc_p, int *p,
195                       warninp_t wi)
196 {
197     char buf[STRLEN];
198
199     if (*p > 0 && *p % nst != 0)
200     {
201         /* Round up to the next multiple of nst */
202         *p = ((*p)/nst + 1)*nst;
203         sprintf(buf, "%s should be a multiple of %s, changing %s to %d\n",
204                 desc_p, desc_nst, desc_p, *p);
205         warning(wi, buf);
206     }
207 }
208
209 static bool ir_NVE(const t_inputrec *ir)
210 {
211     return (EI_MD(ir->eI) && ir->etc == etcNO);
212 }
213
214 static int lcd(int n1, int n2)
215 {
216     int d, i;
217
218     d = 1;
219     for (i = 2; (i <= n1 && i <= n2); i++)
220     {
221         if (n1 % i == 0 && n2 % i == 0)
222         {
223             d = i;
224         }
225     }
226
227     return d;
228 }
229
230 static void process_interaction_modifier(const t_inputrec *ir, int *eintmod)
231 {
232     if (*eintmod == eintmodPOTSHIFT_VERLET)
233     {
234         if (ir->cutoff_scheme == ecutsVERLET)
235         {
236             *eintmod = eintmodPOTSHIFT;
237         }
238         else
239         {
240             *eintmod = eintmodNONE;
241         }
242     }
243 }
244
245 void check_ir(const char *mdparin, t_inputrec *ir, t_gromppopts *opts,
246               warninp_t wi)
247 /* Check internal consistency.
248  * NOTE: index groups are not set here yet, don't check things
249  * like temperature coupling group options here, but in triple_check
250  */
251 {
252     /* Strange macro: first one fills the err_buf, and then one can check
253      * the condition, which will print the message and increase the error
254      * counter.
255      */
256 #define CHECK(b) _low_check(b, err_buf, wi)
257     char        err_buf[256], warn_buf[STRLEN];
258     int         i, j;
259     real        dt_pcoupl;
260     t_lambda   *fep    = ir->fepvals;
261     t_expanded *expand = ir->expandedvals;
262
263     set_warning_line(wi, mdparin, -1);
264
265     if (ir->coulombtype == eelRF_NEC_UNSUPPORTED)
266     {
267         sprintf(warn_buf, "%s electrostatics is no longer supported",
268                 eel_names[eelRF_NEC_UNSUPPORTED]);
269         warning_error(wi, warn_buf);
270     }
271
272     /* BASIC CUT-OFF STUFF */
273     if (ir->rcoulomb < 0)
274     {
275         warning_error(wi, "rcoulomb should be >= 0");
276     }
277     if (ir->rvdw < 0)
278     {
279         warning_error(wi, "rvdw should be >= 0");
280     }
281     if (ir->rlist < 0 &&
282         !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0))
283     {
284         warning_error(wi, "rlist should be >= 0");
285     }
286     sprintf(err_buf, "nstlist can not be smaller than 0. (If you were trying to use the heuristic neighbour-list update scheme for efficient buffering for improved energy conservation, please use the Verlet cut-off scheme instead.)");
287     CHECK(ir->nstlist < 0);
288
289     process_interaction_modifier(ir, &ir->coulomb_modifier);
290     process_interaction_modifier(ir, &ir->vdw_modifier);
291
292     if (ir->cutoff_scheme == ecutsGROUP)
293     {
294         warning_note(wi,
295                      "The group cutoff scheme is deprecated since GROMACS 5.0 and will be removed in a future "
296                      "release when all interaction forms are supported for the verlet scheme. The verlet "
297                      "scheme already scales better, and it is compatible with GPUs and other accelerators.");
298
299         if (ir->rlist > 0 && ir->rlist < ir->rcoulomb)
300         {
301             gmx_fatal(FARGS, "rcoulomb must not be greater than rlist (twin-range schemes are not supported)");
302         }
303         if (ir->rlist > 0 && ir->rlist < ir->rvdw)
304         {
305             gmx_fatal(FARGS, "rvdw must not be greater than rlist (twin-range schemes are not supported)");
306         }
307
308         if (ir->rlist == 0 && ir->ePBC != epbcNONE)
309         {
310             warning_error(wi, "Can not have an infinite cut-off with PBC");
311         }
312     }
313
314     if (ir->cutoff_scheme == ecutsVERLET)
315     {
316         real rc_max;
317
318         /* Normal Verlet type neighbor-list, currently only limited feature support */
319         if (inputrec2nboundeddim(ir) < 3)
320         {
321             warning_error(wi, "With Verlet lists only full pbc or pbc=xy with walls is supported");
322         }
323
324         // We don't (yet) have general Verlet kernels for rcoulomb!=rvdw
325         if (ir->rcoulomb != ir->rvdw)
326         {
327             // Since we have PME coulomb + LJ cut-off kernels with rcoulomb>rvdw
328             // for PME load balancing, we can support this exception.
329             bool bUsesPmeTwinRangeKernel = (EEL_PME_EWALD(ir->coulombtype) &&
330                                             ir->vdwtype == evdwCUT &&
331                                             ir->rcoulomb > ir->rvdw);
332             if (!bUsesPmeTwinRangeKernel)
333             {
334                 warning_error(wi, "With Verlet lists rcoulomb!=rvdw is not supported (except for rcoulomb>rvdw with PME electrostatics)");
335             }
336         }
337
338         if (ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwSWITCH)
339         {
340             if (ir->vdw_modifier == eintmodNONE ||
341                 ir->vdw_modifier == eintmodPOTSHIFT)
342             {
343                 ir->vdw_modifier = (ir->vdwtype == evdwSHIFT ? eintmodFORCESWITCH : eintmodPOTSWITCH);
344
345                 sprintf(warn_buf, "Replacing vdwtype=%s by the equivalent combination of vdwtype=%s and vdw_modifier=%s", evdw_names[ir->vdwtype], evdw_names[evdwCUT], eintmod_names[ir->vdw_modifier]);
346                 warning_note(wi, warn_buf);
347
348                 ir->vdwtype = evdwCUT;
349             }
350             else
351             {
352                 sprintf(warn_buf, "Unsupported combination of vdwtype=%s and vdw_modifier=%s", evdw_names[ir->vdwtype], eintmod_names[ir->vdw_modifier]);
353                 warning_error(wi, warn_buf);
354             }
355         }
356
357         if (!(ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME))
358         {
359             warning_error(wi, "With Verlet lists only cut-off and PME LJ interactions are supported");
360         }
361         if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) ||
362               EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD))
363         {
364             warning_error(wi, "With Verlet lists only cut-off, reaction-field, PME and Ewald electrostatics are supported");
365         }
366         if (!(ir->coulomb_modifier == eintmodNONE ||
367               ir->coulomb_modifier == eintmodPOTSHIFT))
368         {
369             sprintf(warn_buf, "coulomb_modifier=%s is not supported with the Verlet cut-off scheme", eintmod_names[ir->coulomb_modifier]);
370             warning_error(wi, warn_buf);
371         }
372
373         if (EEL_USER(ir->coulombtype))
374         {
375             sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme", eel_names[ir->coulombtype]);
376             warning_error(wi, warn_buf);
377         }
378
379         if (ir->nstlist <= 0)
380         {
381             warning_error(wi, "With Verlet lists nstlist should be larger than 0");
382         }
383
384         if (ir->nstlist < 10)
385         {
386             warning_note(wi, "With Verlet lists the optimal nstlist is >= 10, with GPUs >= 20. Note that with the Verlet scheme, nstlist has no effect on the accuracy of your simulation.");
387         }
388
389         rc_max = std::max(ir->rvdw, ir->rcoulomb);
390
391         if (ir->verletbuf_tol <= 0)
392         {
393             if (ir->verletbuf_tol == 0)
394             {
395                 warning_error(wi, "Can not have Verlet buffer tolerance of exactly 0");
396             }
397
398             if (ir->rlist < rc_max)
399             {
400                 warning_error(wi, "With verlet lists rlist can not be smaller than rvdw or rcoulomb");
401             }
402
403             if (ir->rlist == rc_max && ir->nstlist > 1)
404             {
405                 warning_note(wi, "rlist is equal to rvdw and/or rcoulomb: there is no explicit Verlet buffer. The cluster pair list does have a buffering effect, but choosing a larger rlist might be necessary for good energy conservation.");
406             }
407         }
408         else
409         {
410             if (ir->rlist > rc_max)
411             {
412                 warning_note(wi, "You have set rlist larger than the interaction cut-off, but you also have verlet-buffer-tolerance > 0. Will set rlist using verlet-buffer-tolerance.");
413             }
414
415             if (ir->nstlist == 1)
416             {
417                 /* No buffer required */
418                 ir->rlist = rc_max;
419             }
420             else
421             {
422                 if (EI_DYNAMICS(ir->eI))
423                 {
424                     if (inputrec2nboundeddim(ir) < 3)
425                     {
426                         warning_error(wi, "The box volume is required for calculating rlist from the energy drift with verlet-buffer-tolerance > 0. You are using at least one unbounded dimension, so no volume can be computed. Either use a finite box, or set rlist yourself together with verlet-buffer-tolerance = -1.");
427                     }
428                     /* Set rlist temporarily so we can continue processing */
429                     ir->rlist = rc_max;
430                 }
431                 else
432                 {
433                     /* Set the buffer to 5% of the cut-off */
434                     ir->rlist = (1.0 + verlet_buffer_ratio_nodynamics)*rc_max;
435                 }
436             }
437         }
438     }
439
440     /* GENERAL INTEGRATOR STUFF */
441     if (!EI_MD(ir->eI))
442     {
443         if (ir->etc != etcNO)
444         {
445             if (EI_RANDOM(ir->eI))
446             {
447                 sprintf(warn_buf, "Setting tcoupl from '%s' to 'no'. %s handles temperature coupling implicitly. See the documentation for more information on which parameters affect temperature for %s.", etcoupl_names[ir->etc], ei_names[ir->eI], ei_names[ir->eI]);
448             }
449             else
450             {
451                 sprintf(warn_buf, "Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to %s.", etcoupl_names[ir->etc], ei_names[ir->eI]);
452             }
453             warning_note(wi, warn_buf);
454         }
455         ir->etc = etcNO;
456     }
457     if (ir->eI == eiVVAK)
458     {
459         sprintf(warn_buf, "Integrator method %s is implemented primarily for validation purposes; for molecular dynamics, you should probably be using %s or %s", ei_names[eiVVAK], ei_names[eiMD], ei_names[eiVV]);
460         warning_note(wi, warn_buf);
461     }
462     if (!EI_DYNAMICS(ir->eI))
463     {
464         if (ir->epc != epcNO)
465         {
466             sprintf(warn_buf, "Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.", epcoupl_names[ir->epc], ei_names[ir->eI]);
467             warning_note(wi, warn_buf);
468         }
469         ir->epc = epcNO;
470     }
471     if (EI_DYNAMICS(ir->eI))
472     {
473         if (ir->nstcalcenergy < 0)
474         {
475             ir->nstcalcenergy = ir_optimal_nstcalcenergy(ir);
476             if (ir->nstenergy != 0 && ir->nstenergy < ir->nstcalcenergy)
477             {
478                 /* nstcalcenergy larger than nstener does not make sense.
479                  * We ideally want nstcalcenergy=nstener.
480                  */
481                 if (ir->nstlist > 0)
482                 {
483                     ir->nstcalcenergy = lcd(ir->nstenergy, ir->nstlist);
484                 }
485                 else
486                 {
487                     ir->nstcalcenergy = ir->nstenergy;
488                 }
489             }
490         }
491         else if ( (ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy) ||
492                   (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
493                    (ir->nstcalcenergy > ir->fepvals->nstdhdl) ) )
494
495         {
496             const char *nsten    = "nstenergy";
497             const char *nstdh    = "nstdhdl";
498             const char *min_name = nsten;
499             int         min_nst  = ir->nstenergy;
500
501             /* find the smallest of ( nstenergy, nstdhdl ) */
502             if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
503                 (ir->nstenergy == 0 || ir->fepvals->nstdhdl < ir->nstenergy))
504             {
505                 min_nst  = ir->fepvals->nstdhdl;
506                 min_name = nstdh;
507             }
508             /* If the user sets nstenergy small, we should respect that */
509             sprintf(warn_buf,
510                     "Setting nstcalcenergy (%d) equal to %s (%d)",
511                     ir->nstcalcenergy, min_name, min_nst);
512             warning_note(wi, warn_buf);
513             ir->nstcalcenergy = min_nst;
514         }
515
516         if (ir->epc != epcNO)
517         {
518             if (ir->nstpcouple < 0)
519             {
520                 ir->nstpcouple = ir_optimal_nstpcouple(ir);
521             }
522         }
523
524         if (ir->nstcalcenergy > 0)
525         {
526             if (ir->efep != efepNO)
527             {
528                 /* nstdhdl should be a multiple of nstcalcenergy */
529                 check_nst("nstcalcenergy", ir->nstcalcenergy,
530                           "nstdhdl", &ir->fepvals->nstdhdl, wi);
531             }
532             if (ir->bExpanded)
533             {
534                 /* nstexpanded should be a multiple of nstcalcenergy */
535                 check_nst("nstcalcenergy", ir->nstcalcenergy,
536                           "nstexpanded", &ir->expandedvals->nstexpanded, wi);
537             }
538             /* for storing exact averages nstenergy should be
539              * a multiple of nstcalcenergy
540              */
541             check_nst("nstcalcenergy", ir->nstcalcenergy,
542                       "nstenergy", &ir->nstenergy, wi);
543         }
544     }
545
546     if (ir->nsteps == 0 && !ir->bContinuation)
547     {
548         warning_note(wi, "For a correct single-point energy evaluation with nsteps = 0, use continuation = yes to avoid constraining the input coordinates.");
549     }
550
551     /* LD STUFF */
552     if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
553         ir->bContinuation && ir->ld_seed != -1)
554     {
555         warning_note(wi, "You are doing a continuation with SD or BD, make sure that ld_seed is different from the previous run (using ld_seed=-1 will ensure this)");
556     }
557
558     /* TPI STUFF */
559     if (EI_TPI(ir->eI))
560     {
561         sprintf(err_buf, "TPI only works with pbc = %s", epbc_names[epbcXYZ]);
562         CHECK(ir->ePBC != epbcXYZ);
563         sprintf(err_buf, "TPI only works with ns = %s", ens_names[ensGRID]);
564         CHECK(ir->ns_type != ensGRID);
565         sprintf(err_buf, "with TPI nstlist should be larger than zero");
566         CHECK(ir->nstlist <= 0);
567         sprintf(err_buf, "TPI does not work with full electrostatics other than PME");
568         CHECK(EEL_FULL(ir->coulombtype) && !EEL_PME(ir->coulombtype));
569         sprintf(err_buf, "TPI does not work (yet) with the Verlet cut-off scheme");
570         CHECK(ir->cutoff_scheme == ecutsVERLET);
571     }
572
573     /* SHAKE / LINCS */
574     if ( (opts->nshake > 0) && (opts->bMorse) )
575     {
576         sprintf(warn_buf,
577                 "Using morse bond-potentials while constraining bonds is useless");
578         warning(wi, warn_buf);
579     }
580
581     if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
582         ir->bContinuation && ir->ld_seed != -1)
583     {
584         warning_note(wi, "You are doing a continuation with SD or BD, make sure that ld_seed is different from the previous run (using ld_seed=-1 will ensure this)");
585     }
586     /* verify simulated tempering options */
587
588     if (ir->bSimTemp)
589     {
590         bool bAllTempZero = TRUE;
591         for (i = 0; i < fep->n_lambda; i++)
592         {
593             sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i, efpt_names[efptTEMPERATURE], fep->all_lambda[efptTEMPERATURE][i]);
594             CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
595             if (fep->all_lambda[efptTEMPERATURE][i] > 0)
596             {
597                 bAllTempZero = FALSE;
598             }
599         }
600         sprintf(err_buf, "if simulated tempering is on, temperature-lambdas may not be all zero");
601         CHECK(bAllTempZero == TRUE);
602
603         sprintf(err_buf, "Simulated tempering is currently only compatible with md-vv");
604         CHECK(ir->eI != eiVV);
605
606         /* check compatability of the temperature coupling with simulated tempering */
607
608         if (ir->etc == etcNOSEHOOVER)
609         {
610             sprintf(warn_buf, "Nose-Hoover based temperature control such as [%s] my not be entirelyconsistent with simulated tempering", etcoupl_names[ir->etc]);
611             warning_note(wi, warn_buf);
612         }
613
614         /* check that the temperatures make sense */
615
616         sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= than the simulated tempering lower temperature (%g)", ir->simtempvals->simtemp_high, ir->simtempvals->simtemp_low);
617         CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low);
618
619         sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_high);
620         CHECK(ir->simtempvals->simtemp_high <= 0);
621
622         sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_low);
623         CHECK(ir->simtempvals->simtemp_low <= 0);
624     }
625
626     /* verify free energy options */
627
628     if (ir->efep != efepNO)
629     {
630         fep = ir->fepvals;
631         sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2",
632                 fep->sc_power);
633         CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2);
634
635         sprintf(err_buf, "The soft-core sc-r-power is %d and can only be 6 or 48",
636                 static_cast<int>(fep->sc_r_power));
637         CHECK(fep->sc_alpha != 0 && fep->sc_r_power != 6.0 && fep->sc_r_power != 48.0);
638
639         sprintf(err_buf, "Can't use positive delta-lambda (%g) if initial state/lambda does not start at zero", fep->delta_lambda);
640         CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) ||  (fep->init_lambda > 0)));
641
642         sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations", fep->delta_lambda);
643         CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
644
645         sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)");
646         CHECK(!(EI_VV(ir->eI)) && (ir->efep == efepEXPANDED));
647
648         sprintf(err_buf, "Free-energy not implemented for Ewald");
649         CHECK(ir->coulombtype == eelEWALD);
650
651         /* check validty of lambda inputs */
652         if (fep->n_lambda == 0)
653         {
654             /* Clear output in case of no states:*/
655             sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state);
656             CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0));
657         }
658         else
659         {
660             sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d", fep->init_fep_state, fep->n_lambda-1);
661             CHECK((fep->init_fep_state >= fep->n_lambda));
662         }
663
664         sprintf(err_buf, "Lambda state must be set, either with init-lambda-state or with init-lambda");
665         CHECK((fep->init_fep_state < 0) && (fep->init_lambda < 0));
666
667         sprintf(err_buf, "init-lambda=%g while init-lambda-state=%d. Lambda state must be set either with init-lambda-state or with init-lambda, but not both",
668                 fep->init_lambda, fep->init_fep_state);
669         CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
670
671
672
673         if ((fep->init_lambda >= 0) && (fep->delta_lambda == 0))
674         {
675             int n_lambda_terms;
676             n_lambda_terms = 0;
677             for (i = 0; i < efptNR; i++)
678             {
679                 if (fep->separate_dvdl[i])
680                 {
681                     n_lambda_terms++;
682                 }
683             }
684             if (n_lambda_terms > 1)
685             {
686                 sprintf(warn_buf, "If lambda vector states (fep-lambdas, coul-lambdas etc.) are set, don't use init-lambda to set lambda state (except for slow growth). Use init-lambda-state instead.");
687                 warning(wi, warn_buf);
688             }
689
690             if (n_lambda_terms < 2 && fep->n_lambda > 0)
691             {
692                 warning_note(wi,
693                              "init-lambda is deprecated for setting lambda state (except for slow growth). Use init-lambda-state instead.");
694             }
695         }
696
697         for (j = 0; j < efptNR; j++)
698         {
699             for (i = 0; i < fep->n_lambda; i++)
700             {
701                 sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i, efpt_names[j], fep->all_lambda[j][i]);
702                 CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
703             }
704         }
705
706         if ((fep->sc_alpha > 0) && (!fep->bScCoul))
707         {
708             for (i = 0; i < fep->n_lambda; i++)
709             {
710                 sprintf(err_buf, "For state %d, vdw-lambdas (%f) is changing with vdw softcore, while coul-lambdas (%f) is nonzero without coulomb softcore: this will lead to crashes, and is not supported.", i, fep->all_lambda[efptVDW][i],
711                         fep->all_lambda[efptCOUL][i]);
712                 CHECK((fep->sc_alpha > 0) &&
713                       (((fep->all_lambda[efptCOUL][i] > 0.0) &&
714                         (fep->all_lambda[efptCOUL][i] < 1.0)) &&
715                        ((fep->all_lambda[efptVDW][i] > 0.0) &&
716                         (fep->all_lambda[efptVDW][i] < 1.0))));
717             }
718         }
719
720         if ((fep->bScCoul) && (EEL_PME(ir->coulombtype)))
721         {
722             real sigma, lambda, r_sc;
723
724             sigma  = 0.34;
725             /* Maximum estimate for A and B charges equal with lambda power 1 */
726             lambda = 0.5;
727             r_sc   = std::pow(lambda*fep->sc_alpha*std::pow(sigma/ir->rcoulomb, fep->sc_r_power) + 1.0, 1.0/fep->sc_r_power);
728             sprintf(warn_buf, "With PME there is a minor soft core effect present at the cut-off, proportional to (LJsigma/rcoulomb)^%g. This could have a minor effect on energy conservation, but usually other effects dominate. With a common sigma value of %g nm the fraction of the particle-particle potential at the cut-off at lambda=%g is around %.1e, while ewald-rtol is %.1e.",
729                     fep->sc_r_power,
730                     sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
731             warning_note(wi, warn_buf);
732         }
733
734         /*  Free Energy Checks -- In an ideal world, slow growth and FEP would
735             be treated differently, but that's the next step */
736
737         for (i = 0; i < efptNR; i++)
738         {
739             for (j = 0; j < fep->n_lambda; j++)
740             {
741                 sprintf(err_buf, "%s[%d] must be between 0 and 1", efpt_names[i], j);
742                 CHECK((fep->all_lambda[i][j] < 0) || (fep->all_lambda[i][j] > 1));
743             }
744         }
745     }
746
747     if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
748     {
749         fep    = ir->fepvals;
750
751         /* checking equilibration of weights inputs for validity */
752
753         sprintf(err_buf, "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal to %s",
754                 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
755         CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
756
757         sprintf(err_buf, "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to %s",
758                 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
759         CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
760
761         sprintf(err_buf, "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
762                 expand->equil_steps, elmceq_names[elmceqSTEPS]);
763         CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
764
765         sprintf(err_buf, "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
766                 expand->equil_samples, elmceq_names[elmceqWLDELTA]);
767         CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
768
769         sprintf(err_buf, "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
770                 expand->equil_ratio, elmceq_names[elmceqRATIO]);
771         CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
772
773         sprintf(err_buf, "weight-equil-number-all-lambda (%d) must be a positive integer if lmc-weights-equil=%s",
774                 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
775         CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
776
777         sprintf(err_buf, "weight-equil-number-samples (%d) must be a positive integer if lmc-weights-equil=%s",
778                 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
779         CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
780
781         sprintf(err_buf, "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
782                 expand->equil_steps, elmceq_names[elmceqSTEPS]);
783         CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
784
785         sprintf(err_buf, "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
786                 expand->equil_wl_delta, elmceq_names[elmceqWLDELTA]);
787         CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
788
789         sprintf(err_buf, "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
790                 expand->equil_ratio, elmceq_names[elmceqRATIO]);
791         CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
792
793         sprintf(err_buf, "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
794                 elmceq_names[elmceqWLDELTA], elamstats_names[elamstatsWL], elamstats_names[elamstatsWWL]);
795         CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
796
797         sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
798         CHECK((expand->lmc_repeats <= 0));
799         sprintf(err_buf, "minimum-var-min (%d) must be greater than 0", expand->minvarmin);
800         CHECK((expand->minvarmin <= 0));
801         sprintf(err_buf, "weight-c-range (%d) must be greater or equal to 0", expand->c_range);
802         CHECK((expand->c_range < 0));
803         sprintf(err_buf, "init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != 'no'",
804                 fep->init_fep_state, expand->lmc_forced_nstart);
805         CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0) && (expand->elmcmove != elmcmoveNO));
806         sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
807         CHECK((expand->lmc_forced_nstart < 0));
808         sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)", fep->init_fep_state);
809         CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda));
810
811         sprintf(err_buf, "init-wl-delta (%f) must be greater than or equal to 0", expand->init_wl_delta);
812         CHECK((expand->init_wl_delta < 0));
813         sprintf(err_buf, "wl-ratio (%f) must be between 0 and 1", expand->wl_ratio);
814         CHECK((expand->wl_ratio <= 0) || (expand->wl_ratio >= 1));
815         sprintf(err_buf, "wl-scale (%f) must be between 0 and 1", expand->wl_scale);
816         CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1));
817
818         /* if there is no temperature control, we need to specify an MC temperature */
819         if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO) && (expand->mc_temp <= 0.0))
820         {
821             sprintf(err_buf, "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set to a positive number");
822             warning_error(wi, err_buf);
823         }
824         if (expand->nstTij > 0)
825         {
826             sprintf(err_buf, "nstlog must be non-zero");
827             CHECK(ir->nstlog == 0);
828             sprintf(err_buf, "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
829                     expand->nstTij, ir->nstlog);
830             CHECK((expand->nstTij % ir->nstlog) != 0);
831         }
832     }
833
834     /* PBC/WALLS */
835     sprintf(err_buf, "walls only work with pbc=%s", epbc_names[epbcXY]);
836     CHECK(ir->nwall && ir->ePBC != epbcXY);
837
838     /* VACUUM STUFF */
839     if (ir->ePBC != epbcXYZ && ir->nwall != 2)
840     {
841         if (ir->ePBC == epbcNONE)
842         {
843             if (ir->epc != epcNO)
844             {
845                 warning(wi, "Turning off pressure coupling for vacuum system");
846                 ir->epc = epcNO;
847             }
848         }
849         else
850         {
851             sprintf(err_buf, "Can not have pressure coupling with pbc=%s",
852                     epbc_names[ir->ePBC]);
853             CHECK(ir->epc != epcNO);
854         }
855         sprintf(err_buf, "Can not have Ewald with pbc=%s", epbc_names[ir->ePBC]);
856         CHECK(EEL_FULL(ir->coulombtype));
857
858         sprintf(err_buf, "Can not have dispersion correction with pbc=%s",
859                 epbc_names[ir->ePBC]);
860         CHECK(ir->eDispCorr != edispcNO);
861     }
862
863     if (ir->rlist == 0.0)
864     {
865         sprintf(err_buf, "can only have neighborlist cut-off zero (=infinite)\n"
866                 "with coulombtype = %s or coulombtype = %s\n"
867                 "without periodic boundary conditions (pbc = %s) and\n"
868                 "rcoulomb and rvdw set to zero",
869                 eel_names[eelCUT], eel_names[eelUSER], epbc_names[epbcNONE]);
870         CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER)) ||
871               (ir->ePBC     != epbcNONE) ||
872               (ir->rcoulomb != 0.0)      || (ir->rvdw != 0.0));
873
874         if (ir->nstlist > 0)
875         {
876             warning_note(wi, "Simulating without cut-offs can be (slightly) faster with nstlist=0, nstype=simple and only one MPI rank");
877         }
878     }
879
880     /* COMM STUFF */
881     if (ir->nstcomm == 0)
882     {
883         ir->comm_mode = ecmNO;
884     }
885     if (ir->comm_mode != ecmNO)
886     {
887         if (ir->nstcomm < 0)
888         {
889             warning(wi, "If you want to remove the rotation around the center of mass, you should set comm_mode = Angular instead of setting nstcomm < 0. nstcomm is modified to its absolute value");
890             ir->nstcomm = abs(ir->nstcomm);
891         }
892
893         if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy)
894         {
895             warning_note(wi, "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting nstcomm to nstcalcenergy");
896             ir->nstcomm = ir->nstcalcenergy;
897         }
898
899         if (ir->comm_mode == ecmANGULAR)
900         {
901             sprintf(err_buf, "Can not remove the rotation around the center of mass with periodic molecules");
902             CHECK(ir->bPeriodicMols);
903             if (ir->ePBC != epbcNONE)
904             {
905                 warning(wi, "Removing the rotation around the center of mass in a periodic system, this can lead to artifacts. Only use this on a single (cluster of) molecules. This cluster should not cross periodic boundaries.");
906             }
907         }
908     }
909
910     if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->ePBC == epbcNONE && ir->comm_mode != ecmANGULAR)
911     {
912         sprintf(warn_buf, "Tumbling and flying ice-cubes: We are not removing rotation around center of mass in a non-periodic system. You should probably set comm_mode = ANGULAR or use integrator = %s.", ei_names[eiSD1]);
913         warning_note(wi, warn_buf);
914     }
915
916     /* TEMPERATURE COUPLING */
917     if (ir->etc == etcYES)
918     {
919         ir->etc = etcBERENDSEN;
920         warning_note(wi, "Old option for temperature coupling given: "
921                      "changing \"yes\" to \"Berendsen\"\n");
922     }
923
924     if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
925     {
926         if (ir->opts.nhchainlength < 1)
927         {
928             sprintf(warn_buf, "number of Nose-Hoover chains (currently %d) cannot be less than 1,reset to 1\n", ir->opts.nhchainlength);
929             ir->opts.nhchainlength = 1;
930             warning(wi, warn_buf);
931         }
932
933         if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
934         {
935             warning_note(wi, "leapfrog does not yet support Nose-Hoover chains, nhchainlength reset to 1");
936             ir->opts.nhchainlength = 1;
937         }
938     }
939     else
940     {
941         ir->opts.nhchainlength = 0;
942     }
943
944     if (ir->eI == eiVVAK)
945     {
946         sprintf(err_buf, "%s implemented primarily for validation, and requires nsttcouple = 1 and nstpcouple = 1.",
947                 ei_names[eiVVAK]);
948         CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1));
949     }
950
951     if (ETC_ANDERSEN(ir->etc))
952     {
953         sprintf(err_buf, "%s temperature control not supported for integrator %s.", etcoupl_names[ir->etc], ei_names[ir->eI]);
954         CHECK(!(EI_VV(ir->eI)));
955
956         if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
957         {
958             sprintf(warn_buf, "Center of mass removal not necessary for %s.  All velocities of coupled groups are rerandomized periodically, so flying ice cube errors will not occur.", etcoupl_names[ir->etc]);
959             warning_note(wi, warn_buf);
960         }
961
962         sprintf(err_buf, "nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are randomized every time step", ir->nstcomm, etcoupl_names[ir->etc]);
963         CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
964     }
965
966     if (ir->etc == etcBERENDSEN)
967     {
968         sprintf(warn_buf, "The %s thermostat does not generate the correct kinetic energy distribution. You might want to consider using the %s thermostat.",
969                 ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
970         warning_note(wi, warn_buf);
971     }
972
973     if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc))
974         && ir->epc == epcBERENDSEN)
975     {
976         sprintf(warn_buf, "Using Berendsen pressure coupling invalidates the "
977                 "true ensemble for the thermostat");
978         warning(wi, warn_buf);
979     }
980
981     /* PRESSURE COUPLING */
982     if (ir->epc == epcISOTROPIC)
983     {
984         ir->epc = epcBERENDSEN;
985         warning_note(wi, "Old option for pressure coupling given: "
986                      "changing \"Isotropic\" to \"Berendsen\"\n");
987     }
988
989     if (ir->epc != epcNO)
990     {
991         dt_pcoupl = ir->nstpcouple*ir->delta_t;
992
993         sprintf(err_buf, "tau-p must be > 0 instead of %g\n", ir->tau_p);
994         CHECK(ir->tau_p <= 0);
995
996         if (ir->tau_p/dt_pcoupl < pcouple_min_integration_steps(ir->epc) - 10*GMX_REAL_EPS)
997         {
998             sprintf(warn_buf, "For proper integration of the %s barostat, tau-p (%g) should be at least %d times larger than nstpcouple*dt (%g)",
999                     EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl);
1000             warning(wi, warn_buf);
1001         }
1002
1003         sprintf(err_buf, "compressibility must be > 0 when using pressure"
1004                 " coupling %s\n", EPCOUPLTYPE(ir->epc));
1005         CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 ||
1006               ir->compress[ZZ][ZZ] < 0 ||
1007               (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 &&
1008                ir->compress[ZZ][XX] <= 0 && ir->compress[ZZ][YY] <= 0));
1009
1010         if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
1011         {
1012             sprintf(warn_buf,
1013                     "You are generating velocities so I am assuming you "
1014                     "are equilibrating a system. You are using "
1015                     "%s pressure coupling, but this can be "
1016                     "unstable for equilibration. If your system crashes, try "
1017                     "equilibrating first with Berendsen pressure coupling. If "
1018                     "you are not equilibrating the system, you can probably "
1019                     "ignore this warning.",
1020                     epcoupl_names[ir->epc]);
1021             warning(wi, warn_buf);
1022         }
1023     }
1024
1025     if (EI_VV(ir->eI))
1026     {
1027         if (ir->epc > epcNO)
1028         {
1029             if ((ir->epc != epcBERENDSEN) && (ir->epc != epcMTTK))
1030             {
1031                 warning_error(wi, "for md-vv and md-vv-avek, can only use Berendsen and Martyna-Tuckerman-Tobias-Klein (MTTK) equations for pressure control; MTTK is equivalent to Parrinello-Rahman.");
1032             }
1033         }
1034     }
1035     else
1036     {
1037         if (ir->epc == epcMTTK)
1038         {
1039             warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
1040         }
1041     }
1042
1043     /* ELECTROSTATICS */
1044     /* More checks are in triple check (grompp.c) */
1045
1046     if (ir->coulombtype == eelSWITCH)
1047     {
1048         sprintf(warn_buf, "coulombtype = %s is only for testing purposes and can lead to serious "
1049                 "artifacts, advice: use coulombtype = %s",
1050                 eel_names[ir->coulombtype],
1051                 eel_names[eelRF_ZERO]);
1052         warning(wi, warn_buf);
1053     }
1054
1055     if (EEL_RF(ir->coulombtype) && ir->epsilon_rf == 1 && ir->epsilon_r != 1)
1056     {
1057         sprintf(warn_buf, "epsilon-r = %g and epsilon-rf = 1 with reaction field, proceeding assuming old format and exchanging epsilon-r and epsilon-rf", ir->epsilon_r);
1058         warning(wi, warn_buf);
1059         ir->epsilon_rf = ir->epsilon_r;
1060         ir->epsilon_r  = 1.0;
1061     }
1062
1063     if (ir->epsilon_r == 0)
1064     {
1065         sprintf(err_buf,
1066                 "It is pointless to use long-range electrostatics with infinite relative permittivity."
1067                 "Since you are effectively turning of electrostatics, a plain cutoff will be much faster.");
1068         CHECK(EEL_FULL(ir->coulombtype));
1069     }
1070
1071     if (getenv("GMX_DO_GALACTIC_DYNAMICS") == nullptr)
1072     {
1073         sprintf(err_buf, "epsilon-r must be >= 0 instead of %g\n", ir->epsilon_r);
1074         CHECK(ir->epsilon_r < 0);
1075     }
1076
1077     if (EEL_RF(ir->coulombtype))
1078     {
1079         /* reaction field (at the cut-off) */
1080
1081         if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0)
1082         {
1083             sprintf(warn_buf, "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0",
1084                     eel_names[ir->coulombtype]);
1085             warning(wi, warn_buf);
1086             ir->epsilon_rf = 0.0;
1087         }
1088
1089         sprintf(err_buf, "epsilon-rf must be >= epsilon-r");
1090         CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) ||
1091               (ir->epsilon_r == 0));
1092         if (ir->epsilon_rf == ir->epsilon_r)
1093         {
1094             sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense",
1095                     eel_names[ir->coulombtype]);
1096             warning(wi, warn_buf);
1097         }
1098     }
1099     /* Allow rlist>rcoulomb for tabulated long range stuff. This just
1100      * means the interaction is zero outside rcoulomb, but it helps to
1101      * provide accurate energy conservation.
1102      */
1103     if (ir_coulomb_might_be_zero_at_cutoff(ir))
1104     {
1105         if (ir_coulomb_switched(ir))
1106         {
1107             sprintf(err_buf,
1108                     "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the potential modifier options!",
1109                     eel_names[ir->coulombtype]);
1110             CHECK(ir->rcoulomb_switch >= ir->rcoulomb);
1111         }
1112     }
1113     else if (ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype))
1114     {
1115         if (ir->cutoff_scheme == ecutsGROUP && ir->coulomb_modifier == eintmodNONE)
1116         {
1117             sprintf(err_buf, "With coulombtype = %s, rcoulomb should be >= rlist unless you use a potential modifier",
1118                     eel_names[ir->coulombtype]);
1119             CHECK(ir->rlist > ir->rcoulomb);
1120         }
1121     }
1122
1123     if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT)
1124     {
1125         sprintf(err_buf,
1126                 "Explicit switch/shift coulomb interactions cannot be used in combination with a secondary coulomb-modifier.");
1127         CHECK( ir->coulomb_modifier != eintmodNONE);
1128     }
1129     if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1130     {
1131         sprintf(err_buf,
1132                 "Explicit switch/shift vdw interactions cannot be used in combination with a secondary vdw-modifier.");
1133         CHECK( ir->vdw_modifier != eintmodNONE);
1134     }
1135
1136     if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT ||
1137         ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1138     {
1139         sprintf(warn_buf,
1140                 "The switch/shift interaction settings are just for compatibility; you will get better "
1141                 "performance from applying potential modifiers to your interactions!\n");
1142         warning_note(wi, warn_buf);
1143     }
1144
1145     if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH)
1146     {
1147         if (ir->rcoulomb_switch/ir->rcoulomb < 0.9499)
1148         {
1149             real percentage  = 100*(ir->rcoulomb-ir->rcoulomb_switch)/ir->rcoulomb;
1150             sprintf(warn_buf, "The switching range should be 5%% or less (currently %.2f%% using a switching range of %4f-%4f) for accurate electrostatic energies, energy conservation will be good regardless, since ewald_rtol = %g.",
1151                     percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol);
1152             warning(wi, warn_buf);
1153         }
1154     }
1155
1156     if (ir->vdwtype == evdwSWITCH || ir->vdw_modifier == eintmodPOTSWITCH)
1157     {
1158         if (ir->rvdw_switch == 0)
1159         {
1160             sprintf(warn_buf, "rvdw-switch is equal 0 even though you are using a switched Lennard-Jones potential.  This suggests it was not set in the mdp, which can lead to large energy errors.  In GROMACS, 0.05 to 0.1 nm is often a reasonable vdw switching range.");
1161             warning(wi, warn_buf);
1162         }
1163     }
1164
1165     if (EEL_FULL(ir->coulombtype))
1166     {
1167         if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER ||
1168             ir->coulombtype == eelPMEUSERSWITCH)
1169         {
1170             sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist",
1171                     eel_names[ir->coulombtype]);
1172             CHECK(ir->rcoulomb > ir->rlist);
1173         }
1174         else if (ir->cutoff_scheme == ecutsGROUP && ir->coulomb_modifier == eintmodNONE)
1175         {
1176             if (ir->coulombtype == eelPME || ir->coulombtype == eelP3M_AD)
1177             {
1178                 sprintf(err_buf,
1179                         "With coulombtype = %s (without modifier), rcoulomb must be equal to rlist.\n"
1180                         "For optimal energy conservation,consider using\n"
1181                         "a potential modifier.", eel_names[ir->coulombtype]);
1182                 CHECK(ir->rcoulomb != ir->rlist);
1183             }
1184         }
1185     }
1186
1187     if (EEL_PME(ir->coulombtype) || EVDW_PME(ir->vdwtype))
1188     {
1189         // TODO: Move these checks into the ewald module with the options class
1190         int orderMin = 3;
1191         int orderMax = (ir->coulombtype == eelP3M_AD ? 8 : 12);
1192
1193         if (ir->pme_order < orderMin || ir->pme_order > orderMax)
1194         {
1195             sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d", eel_names[ir->coulombtype], orderMin, orderMax);
1196             warning_error(wi, warn_buf);
1197         }
1198     }
1199
1200     if (ir->nwall == 2 && EEL_FULL(ir->coulombtype))
1201     {
1202         if (ir->ewald_geometry == eewg3D)
1203         {
1204             sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s",
1205                     epbc_names[ir->ePBC], eewg_names[eewg3DC]);
1206             warning(wi, warn_buf);
1207         }
1208         /* This check avoids extra pbc coding for exclusion corrections */
1209         sprintf(err_buf, "wall-ewald-zfac should be >= 2");
1210         CHECK(ir->wall_ewald_zfac < 2);
1211     }
1212     if ((ir->ewald_geometry == eewg3DC) && (ir->ePBC != epbcXY) &&
1213         EEL_FULL(ir->coulombtype))
1214     {
1215         sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s",
1216                 eel_names[ir->coulombtype], eewg_names[eewg3DC], epbc_names[epbcXY]);
1217         warning(wi, warn_buf);
1218     }
1219     if ((ir->epsilon_surface != 0) && EEL_FULL(ir->coulombtype))
1220     {
1221         if (ir->cutoff_scheme == ecutsVERLET)
1222         {
1223             sprintf(warn_buf, "Since molecules/charge groups are broken using the Verlet scheme, you can not use a dipole correction to the %s electrostatics.",
1224                     eel_names[ir->coulombtype]);
1225             warning(wi, warn_buf);
1226         }
1227         else
1228         {
1229             sprintf(warn_buf, "Dipole corrections to %s electrostatics only work if all charge groups that can cross PBC boundaries are dipoles. If this is not the case set epsilon_surface to 0",
1230                     eel_names[ir->coulombtype]);
1231             warning_note(wi, warn_buf);
1232         }
1233     }
1234
1235     if (ir_vdw_switched(ir))
1236     {
1237         sprintf(err_buf, "With switched vdw forces or potentials, rvdw-switch must be < rvdw");
1238         CHECK(ir->rvdw_switch >= ir->rvdw);
1239
1240         if (ir->rvdw_switch < 0.5*ir->rvdw)
1241         {
1242             sprintf(warn_buf, "You are applying a switch function to vdw forces or potentials from %g to %g nm, which is more than half the interaction range, whereas switch functions are intended to act only close to the cut-off.",
1243                     ir->rvdw_switch, ir->rvdw);
1244             warning_note(wi, warn_buf);
1245         }
1246     }
1247     else if (ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME)
1248     {
1249         if (ir->cutoff_scheme == ecutsGROUP && ir->vdw_modifier == eintmodNONE)
1250         {
1251             sprintf(err_buf, "With vdwtype = %s, rvdw must be >= rlist unless you use a potential modifier", evdw_names[ir->vdwtype]);
1252             CHECK(ir->rlist > ir->rvdw);
1253         }
1254     }
1255
1256     if (ir->vdwtype == evdwPME)
1257     {
1258         if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
1259         {
1260             sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s",
1261                     evdw_names[ir->vdwtype],
1262                     eintmod_names[eintmodPOTSHIFT],
1263                     eintmod_names[eintmodNONE]);
1264             warning_error(wi, err_buf);
1265         }
1266     }
1267
1268     if (ir->cutoff_scheme == ecutsGROUP)
1269     {
1270         if (((ir->coulomb_modifier != eintmodNONE && ir->rcoulomb == ir->rlist) ||
1271              (ir->vdw_modifier != eintmodNONE && ir->rvdw == ir->rlist)))
1272         {
1273             warning_note(wi, "With exact cut-offs, rlist should be "
1274                          "larger than rcoulomb and rvdw, so that there "
1275                          "is a buffer region for particle motion "
1276                          "between neighborsearch steps");
1277         }
1278
1279         if (ir_coulomb_is_zero_at_cutoff(ir) && ir->rlist <= ir->rcoulomb)
1280         {
1281             sprintf(warn_buf, "For energy conservation with switch/shift potentials, rlist should be 0.1 to 0.3 nm larger than rcoulomb.");
1282             warning_note(wi, warn_buf);
1283         }
1284         if (ir_vdw_switched(ir) && (ir->rlist <= ir->rvdw))
1285         {
1286             sprintf(warn_buf, "For energy conservation with switch/shift potentials, rlist should be 0.1 to 0.3 nm larger than rvdw.");
1287             warning_note(wi, warn_buf);
1288         }
1289     }
1290
1291     if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO)
1292     {
1293         warning_note(wi, "You have selected user tables with dispersion correction, the dispersion will be corrected to -C6/r^6 beyond rvdw_switch (the tabulated interaction between rvdw_switch and rvdw will not be double counted). Make sure that you really want dispersion correction to -C6/r^6.");
1294     }
1295
1296     if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT)
1297         && ir->rvdw != 0)
1298     {
1299         warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off.");
1300     }
1301
1302     if (ir->eI == eiLBFGS && ir->nbfgscorr <= 0)
1303     {
1304         warning(wi, "Using L-BFGS with nbfgscorr<=0 just gets you steepest descent.");
1305     }
1306
1307     /* ENERGY CONSERVATION */
1308     if (ir_NVE(ir) && ir->cutoff_scheme == ecutsGROUP)
1309     {
1310         if (!ir_vdw_might_be_zero_at_cutoff(ir) && ir->rvdw > 0 && ir->vdw_modifier == eintmodNONE)
1311         {
1312             sprintf(warn_buf, "You are using a cut-off for VdW interactions with NVE, for good energy conservation use vdwtype = %s (possibly with DispCorr)",
1313                     evdw_names[evdwSHIFT]);
1314             warning_note(wi, warn_buf);
1315         }
1316         if (!ir_coulomb_might_be_zero_at_cutoff(ir) && ir->rcoulomb > 0)
1317         {
1318             sprintf(warn_buf, "You are using a cut-off for electrostatics with NVE, for good energy conservation use coulombtype = %s or %s",
1319                     eel_names[eelPMESWITCH], eel_names[eelRF_ZERO]);
1320             warning_note(wi, warn_buf);
1321         }
1322     }
1323
1324     /* IMPLICIT SOLVENT */
1325     if (ir->coulombtype == eelGB_NOTUSED)
1326     {
1327         sprintf(warn_buf, "Invalid option %s for coulombtype",
1328                 eel_names[ir->coulombtype]);
1329         warning_error(wi, warn_buf);
1330     }
1331
1332     if (ir->bQMMM)
1333     {
1334         if (ir->cutoff_scheme != ecutsGROUP)
1335         {
1336             warning_error(wi, "QMMM is currently only supported with cutoff-scheme=group");
1337         }
1338         if (!EI_DYNAMICS(ir->eI))
1339         {
1340             char buf[STRLEN];
1341             sprintf(buf, "QMMM is only supported with dynamics, not with integrator %s", ei_names[ir->eI]);
1342             warning_error(wi, buf);
1343         }
1344     }
1345
1346     if (ir->bAdress)
1347     {
1348         gmx_fatal(FARGS, "AdResS simulations are no longer supported");
1349     }
1350 }
1351
1352 /* interpret a number of doubles from a string and put them in an array,
1353    after allocating space for them.
1354    str = the input string
1355    n = the (pre-allocated) number of doubles read
1356    r = the output array of doubles. */
1357 static void parse_n_real(char *str, int *n, real **r, warninp_t wi)
1358 {
1359     auto values = gmx::splitString(str);
1360     *n = values.size();
1361
1362     snew(*r, *n);
1363     for (int i = 0; i < *n; i++)
1364     {
1365         try
1366         {
1367             (*r)[i] = gmx::fromString<real>(values[i]);
1368         }
1369         catch (gmx::GromacsException &)
1370         {
1371             warning_error(wi, "Invalid value " + values[i] + " in string in mdp file. Expected a real number.");
1372         }
1373     }
1374 }
1375
1376
1377 static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi)
1378 {
1379
1380     int         i, j, max_n_lambda, nweights, nfep[efptNR];
1381     t_lambda   *fep    = ir->fepvals;
1382     t_expanded *expand = ir->expandedvals;
1383     real      **count_fep_lambdas;
1384     bool        bOneLambda = TRUE;
1385
1386     snew(count_fep_lambdas, efptNR);
1387
1388     /* FEP input processing */
1389     /* first, identify the number of lambda values for each type.
1390        All that are nonzero must have the same number */
1391
1392     for (i = 0; i < efptNR; i++)
1393     {
1394         parse_n_real(fep_lambda[i], &(nfep[i]), &(count_fep_lambdas[i]), wi);
1395     }
1396
1397     /* now, determine the number of components.  All must be either zero, or equal. */
1398
1399     max_n_lambda = 0;
1400     for (i = 0; i < efptNR; i++)
1401     {
1402         if (nfep[i] > max_n_lambda)
1403         {
1404             max_n_lambda = nfep[i];  /* here's a nonzero one.  All of them
1405                                         must have the same number if its not zero.*/
1406             break;
1407         }
1408     }
1409
1410     for (i = 0; i < efptNR; i++)
1411     {
1412         if (nfep[i] == 0)
1413         {
1414             ir->fepvals->separate_dvdl[i] = FALSE;
1415         }
1416         else if (nfep[i] == max_n_lambda)
1417         {
1418             if (i != efptTEMPERATURE)  /* we treat this differently -- not really a reason to compute the derivative with
1419                                           respect to the temperature currently */
1420             {
1421                 ir->fepvals->separate_dvdl[i] = TRUE;
1422             }
1423         }
1424         else
1425         {
1426             gmx_fatal(FARGS, "Number of lambdas (%d) for FEP type %s not equal to number of other types (%d)",
1427                       nfep[i], efpt_names[i], max_n_lambda);
1428         }
1429     }
1430     /* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
1431     ir->fepvals->separate_dvdl[efptTEMPERATURE] = FALSE;
1432
1433     /* the number of lambdas is the number we've read in, which is either zero
1434        or the same for all */
1435     fep->n_lambda = max_n_lambda;
1436
1437     /* allocate space for the array of lambda values */
1438     snew(fep->all_lambda, efptNR);
1439     /* if init_lambda is defined, we need to set lambda */
1440     if ((fep->init_lambda > 0) && (fep->n_lambda == 0))
1441     {
1442         ir->fepvals->separate_dvdl[efptFEP] = TRUE;
1443     }
1444     /* otherwise allocate the space for all of the lambdas, and transfer the data */
1445     for (i = 0; i < efptNR; i++)
1446     {
1447         snew(fep->all_lambda[i], fep->n_lambda);
1448         if (nfep[i] > 0)  /* if it's zero, then the count_fep_lambda arrays
1449                              are zero */
1450         {
1451             for (j = 0; j < fep->n_lambda; j++)
1452             {
1453                 fep->all_lambda[i][j] = static_cast<double>(count_fep_lambdas[i][j]);
1454             }
1455             sfree(count_fep_lambdas[i]);
1456         }
1457     }
1458     sfree(count_fep_lambdas);
1459
1460     /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for internal
1461        bookkeeping -- for now, init_lambda */
1462
1463     if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
1464     {
1465         for (i = 0; i < fep->n_lambda; i++)
1466         {
1467             fep->all_lambda[efptFEP][i] = fep->init_lambda;
1468         }
1469     }
1470
1471     /* check to see if only a single component lambda is defined, and soft core is defined.
1472        In this case, turn on coulomb soft core */
1473
1474     if (max_n_lambda == 0)
1475     {
1476         bOneLambda = TRUE;
1477     }
1478     else
1479     {
1480         for (i = 0; i < efptNR; i++)
1481         {
1482             if ((nfep[i] != 0) && (i != efptFEP))
1483             {
1484                 bOneLambda = FALSE;
1485             }
1486         }
1487     }
1488     if ((bOneLambda) && (fep->sc_alpha > 0))
1489     {
1490         fep->bScCoul = TRUE;
1491     }
1492
1493     /* Fill in the others with the efptFEP if they are not explicitly
1494        specified (i.e. nfep[i] == 0).  This means if fep is not defined,
1495        they are all zero. */
1496
1497     for (i = 0; i < efptNR; i++)
1498     {
1499         if ((nfep[i] == 0) && (i != efptFEP))
1500         {
1501             for (j = 0; j < fep->n_lambda; j++)
1502             {
1503                 fep->all_lambda[i][j] = fep->all_lambda[efptFEP][j];
1504             }
1505         }
1506     }
1507
1508
1509     /* make it easier if sc_r_power = 48 by increasing it to the 4th power, to be in the right scale. */
1510     if (fep->sc_r_power == 48)
1511     {
1512         if (fep->sc_alpha > 0.1)
1513         {
1514             gmx_fatal(FARGS, "sc_alpha (%f) for sc_r_power = 48 should usually be between 0.001 and 0.004", fep->sc_alpha);
1515         }
1516     }
1517
1518     /* now read in the weights */
1519     parse_n_real(weights, &nweights, &(expand->init_lambda_weights), wi);
1520     if (nweights == 0)
1521     {
1522         snew(expand->init_lambda_weights, fep->n_lambda); /* initialize to zero */
1523     }
1524     else if (nweights != fep->n_lambda)
1525     {
1526         gmx_fatal(FARGS, "Number of weights (%d) is not equal to number of lambda values (%d)",
1527                   nweights, fep->n_lambda);
1528     }
1529     if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
1530     {
1531         expand->nstexpanded = fep->nstdhdl;
1532         /* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
1533     }
1534     if ((expand->nstexpanded < 0) && ir->bSimTemp)
1535     {
1536         expand->nstexpanded = 2*static_cast<int>(ir->opts.tau_t[0]/ir->delta_t);
1537         /* if you don't specify nstexpanded when doing expanded ensemble simulated tempering, it is set to
1538            2*tau_t just to be careful so it's not to frequent  */
1539     }
1540 }
1541
1542
1543 static void do_simtemp_params(t_inputrec *ir)
1544 {
1545
1546     snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda);
1547     GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]);
1548 }
1549
1550 static void
1551 convertYesNos(warninp_t /*wi*/, gmx::ArrayRef<const std::string> inputs, const char * /*name*/, gmx_bool *outputs)
1552 {
1553     int i = 0;
1554     for (const auto &input : inputs)
1555     {
1556         outputs[i] = (gmx_strncasecmp(input.c_str(), "Y", 1) == 0);
1557         ++i;
1558     }
1559 }
1560
1561 template <typename T> void
1562 convertInts(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, T *outputs)
1563 {
1564     int i = 0;
1565     for (const auto &input : inputs)
1566     {
1567         try
1568         {
1569             outputs[i] = gmx::fromStdString<T>(input);
1570         }
1571         catch (gmx::GromacsException &)
1572         {
1573             auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of integers separated by spaces.",
1574                                              name, name);
1575             warning_error(wi, message);
1576         }
1577         ++i;
1578     }
1579 }
1580
1581 static void
1582 convertReals(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, real *outputs)
1583 {
1584     int i = 0;
1585     for (const auto &input : inputs)
1586     {
1587         try
1588         {
1589             outputs[i] = gmx::fromString<real>(input);
1590         }
1591         catch (gmx::GromacsException &)
1592         {
1593             auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1594                                              name, name);
1595             warning_error(wi, message);
1596         }
1597         ++i;
1598     }
1599 }
1600
1601 static void
1602 convertRvecs(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, rvec *outputs)
1603 {
1604     int i = 0, d = 0;
1605     for (const auto &input : inputs)
1606     {
1607         try
1608         {
1609             outputs[i][d] = gmx::fromString<real>(input);
1610         }
1611         catch (gmx::GromacsException &)
1612         {
1613             auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1614                                              name, name);
1615             warning_error(wi, message);
1616         }
1617         ++d;
1618         if (d == DIM)
1619         {
1620             d = 0;
1621             ++i;
1622         }
1623     }
1624 }
1625
1626 static void do_wall_params(t_inputrec *ir,
1627                            char *wall_atomtype, char *wall_density,
1628                            t_gromppopts *opts,
1629                            warninp_t wi)
1630 {
1631     opts->wall_atomtype[0] = nullptr;
1632     opts->wall_atomtype[1] = nullptr;
1633
1634     ir->wall_atomtype[0] = -1;
1635     ir->wall_atomtype[1] = -1;
1636     ir->wall_density[0]  = 0;
1637     ir->wall_density[1]  = 0;
1638
1639     if (ir->nwall > 0)
1640     {
1641         auto wallAtomTypes = gmx::splitString(wall_atomtype);
1642         if (wallAtomTypes.size() != size_t(ir->nwall))
1643         {
1644             gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu",
1645                       ir->nwall, wallAtomTypes.size());
1646         }
1647         for (int i = 0; i < ir->nwall; i++)
1648         {
1649             opts->wall_atomtype[i] = gmx_strdup(wallAtomTypes[i].c_str());
1650         }
1651
1652         if (ir->wall_type == ewt93 || ir->wall_type == ewt104)
1653         {
1654             auto wallDensity = gmx::splitString(wall_density);
1655             if (wallDensity.size() != size_t(ir->nwall))
1656             {
1657                 gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall, wallDensity.size());
1658             }
1659             convertReals(wi, wallDensity, "wall-density", ir->wall_density);
1660             for (int i = 0; i < ir->nwall; i++)
1661             {
1662                 if (ir->wall_density[i] <= 0)
1663                 {
1664                     gmx_fatal(FARGS, "wall-density[%d] = %f\n", i, ir->wall_density[i]);
1665                 }
1666             }
1667         }
1668     }
1669 }
1670
1671 static void add_wall_energrps(gmx_groups_t *groups, int nwall, t_symtab *symtab)
1672 {
1673     int     i;
1674     t_grps *grps;
1675     char    str[STRLEN];
1676
1677     if (nwall > 0)
1678     {
1679         srenew(groups->grpname, groups->ngrpname+nwall);
1680         grps = &(groups->grps[egcENER]);
1681         srenew(grps->nm_ind, grps->nr+nwall);
1682         for (i = 0; i < nwall; i++)
1683         {
1684             sprintf(str, "wall%d", i);
1685             groups->grpname[groups->ngrpname] = put_symtab(symtab, str);
1686             grps->nm_ind[grps->nr++]          = groups->ngrpname++;
1687         }
1688     }
1689 }
1690
1691 static void read_expandedparams(std::vector<t_inpfile> *inp,
1692                                 t_expanded *expand, warninp_t wi)
1693 {
1694     /* read expanded ensemble parameters */
1695     printStringNewline(inp, "expanded ensemble variables");
1696     expand->nstexpanded    = get_eint(inp, "nstexpanded", -1, wi);
1697     expand->elamstats      = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
1698     expand->elmcmove       = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
1699     expand->elmceq         = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
1700     expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
1701     expand->equil_samples  = get_eint(inp, "weight-equil-number-samples", -1, wi);
1702     expand->equil_steps    = get_eint(inp, "weight-equil-number-steps", -1, wi);
1703     expand->equil_wl_delta = get_ereal(inp, "weight-equil-wl-delta", -1, wi);
1704     expand->equil_ratio    = get_ereal(inp, "weight-equil-count-ratio", -1, wi);
1705     printStringNewline(inp, "Seed for Monte Carlo in lambda space");
1706     expand->lmc_seed            = get_eint(inp, "lmc-seed", -1, wi);
1707     expand->mc_temp             = get_ereal(inp, "mc-temperature", -1, wi);
1708     expand->lmc_repeats         = get_eint(inp, "lmc-repeats", 1, wi);
1709     expand->gibbsdeltalam       = get_eint(inp, "lmc-gibbsdelta", -1, wi);
1710     expand->lmc_forced_nstart   = get_eint(inp, "lmc-forced-nstart", 0, wi);
1711     expand->bSymmetrizedTMatrix = (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0);
1712     expand->nstTij              = get_eint(inp, "nst-transition-matrix", -1, wi);
1713     expand->minvarmin           = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
1714     expand->c_range             = get_eint(inp, "weight-c-range", 0, wi);    /* default is just C=0 */
1715     expand->wl_scale            = get_ereal(inp, "wl-scale", 0.8, wi);
1716     expand->wl_ratio            = get_ereal(inp, "wl-ratio", 0.8, wi);
1717     expand->init_wl_delta       = get_ereal(inp, "init-wl-delta", 1.0, wi);
1718     expand->bWLoneovert         = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
1719 }
1720
1721 /*! \brief Return whether an end state with the given coupling-lambda
1722  * value describes fully-interacting VDW.
1723  *
1724  * \param[in]  couple_lambda_value  Enumeration ecouplam value describing the end state
1725  * \return                          Whether VDW is on (i.e. the user chose vdw or vdw-q in the .mdp file)
1726  */
1727 static bool couple_lambda_has_vdw_on(int couple_lambda_value)
1728 {
1729     return (couple_lambda_value == ecouplamVDW ||
1730             couple_lambda_value == ecouplamVDWQ);
1731 }
1732
1733 namespace
1734 {
1735
1736 class MdpErrorHandler : public gmx::IKeyValueTreeErrorHandler
1737 {
1738     public:
1739         explicit MdpErrorHandler(warninp_t wi)
1740             : wi_(wi), mapping_(nullptr)
1741         {
1742         }
1743
1744         void setBackMapping(const gmx::IKeyValueTreeBackMapping &mapping)
1745         {
1746             mapping_ = &mapping;
1747         }
1748
1749         bool onError(gmx::UserInputError *ex, const gmx::KeyValueTreePath &context) override
1750         {
1751             ex->prependContext(gmx::formatString("Error in mdp option \"%s\":",
1752                                                  getOptionName(context).c_str()));
1753             std::string message = gmx::formatExceptionMessageToString(*ex);
1754             warning_error(wi_, message.c_str());
1755             return true;
1756         }
1757
1758     private:
1759         std::string getOptionName(const gmx::KeyValueTreePath &context)
1760         {
1761             if (mapping_ != nullptr)
1762             {
1763                 gmx::KeyValueTreePath path = mapping_->originalPath(context);
1764                 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
1765                 return path[0];
1766             }
1767             GMX_ASSERT(context.size() == 1, "Inconsistent context for mdp option parsing");
1768             return context[0];
1769         }
1770
1771         warninp_t                            wi_;
1772         const gmx::IKeyValueTreeBackMapping *mapping_;
1773 };
1774
1775 } // namespace
1776
1777 void get_ir(const char *mdparin, const char *mdparout,
1778             gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
1779             WriteMdpHeader writeMdpHeader, warninp_t wi)
1780 {
1781     char                  *dumstr[2];
1782     double                 dumdub[2][6];
1783     int                    i, j, m;
1784     char                   warn_buf[STRLEN];
1785     t_lambda              *fep    = ir->fepvals;
1786     t_expanded            *expand = ir->expandedvals;
1787
1788     const char            *no_names[] = { "no", nullptr };
1789
1790     init_inputrec_strings();
1791     gmx::TextInputFile     stream(mdparin);
1792     std::vector<t_inpfile> inp = read_inpfile(&stream, mdparin, wi);
1793
1794     snew(dumstr[0], STRLEN);
1795     snew(dumstr[1], STRLEN);
1796
1797     if (-1 == search_einp(inp, "cutoff-scheme"))
1798     {
1799         sprintf(warn_buf,
1800                 "%s did not specify a value for the .mdp option "
1801                 "\"cutoff-scheme\". Probably it was first intended for use "
1802                 "with GROMACS before 4.6. In 4.6, the Verlet scheme was "
1803                 "introduced, but the group scheme was still the default. "
1804                 "The default is now the Verlet scheme, so you will observe "
1805                 "different behaviour.", mdparin);
1806         warning_note(wi, warn_buf);
1807     }
1808
1809     /* ignore the following deprecated commands */
1810     replace_inp_entry(inp, "title", nullptr);
1811     replace_inp_entry(inp, "cpp", nullptr);
1812     replace_inp_entry(inp, "domain-decomposition", nullptr);
1813     replace_inp_entry(inp, "andersen-seed", nullptr);
1814     replace_inp_entry(inp, "dihre", nullptr);
1815     replace_inp_entry(inp, "dihre-fc", nullptr);
1816     replace_inp_entry(inp, "dihre-tau", nullptr);
1817     replace_inp_entry(inp, "nstdihreout", nullptr);
1818     replace_inp_entry(inp, "nstcheckpoint", nullptr);
1819     replace_inp_entry(inp, "optimize-fft", nullptr);
1820     replace_inp_entry(inp, "adress_type", nullptr);
1821     replace_inp_entry(inp, "adress_const_wf", nullptr);
1822     replace_inp_entry(inp, "adress_ex_width", nullptr);
1823     replace_inp_entry(inp, "adress_hy_width", nullptr);
1824     replace_inp_entry(inp, "adress_ex_forcecap", nullptr);
1825     replace_inp_entry(inp, "adress_interface_correction", nullptr);
1826     replace_inp_entry(inp, "adress_site", nullptr);
1827     replace_inp_entry(inp, "adress_reference_coords", nullptr);
1828     replace_inp_entry(inp, "adress_tf_grp_names", nullptr);
1829     replace_inp_entry(inp, "adress_cg_grp_names", nullptr);
1830     replace_inp_entry(inp, "adress_do_hybridpairs", nullptr);
1831     replace_inp_entry(inp, "rlistlong", nullptr);
1832     replace_inp_entry(inp, "nstcalclr", nullptr);
1833     replace_inp_entry(inp, "pull-print-com2", nullptr);
1834     replace_inp_entry(inp, "gb-algorithm", nullptr);
1835     replace_inp_entry(inp, "nstgbradii", nullptr);
1836     replace_inp_entry(inp, "rgbradii", nullptr);
1837     replace_inp_entry(inp, "gb-epsilon-solvent", nullptr);
1838     replace_inp_entry(inp, "gb-saltconc", nullptr);
1839     replace_inp_entry(inp, "gb-obc-alpha", nullptr);
1840     replace_inp_entry(inp, "gb-obc-beta", nullptr);
1841     replace_inp_entry(inp, "gb-obc-gamma", nullptr);
1842     replace_inp_entry(inp, "gb-dielectric-offset", nullptr);
1843     replace_inp_entry(inp, "sa-algorithm", nullptr);
1844     replace_inp_entry(inp, "sa-surface-tension", nullptr);
1845
1846     /* replace the following commands with the clearer new versions*/
1847     replace_inp_entry(inp, "unconstrained-start", "continuation");
1848     replace_inp_entry(inp, "foreign-lambda", "fep-lambdas");
1849     replace_inp_entry(inp, "verlet-buffer-drift", "verlet-buffer-tolerance");
1850     replace_inp_entry(inp, "nstxtcout", "nstxout-compressed");
1851     replace_inp_entry(inp, "xtc-grps", "compressed-x-grps");
1852     replace_inp_entry(inp, "xtc-precision", "compressed-x-precision");
1853     replace_inp_entry(inp, "pull-print-com1", "pull-print-com");
1854
1855     printStringNewline(&inp, "VARIOUS PREPROCESSING OPTIONS");
1856     printStringNoNewline(&inp, "Preprocessor information: use cpp syntax.");
1857     printStringNoNewline(&inp, "e.g.: -I/home/joe/doe -I/home/mary/roe");
1858     setStringEntry(&inp, "include", opts->include,  nullptr);
1859     printStringNoNewline(&inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)");
1860     setStringEntry(&inp, "define",  opts->define,   nullptr);
1861
1862     printStringNewline(&inp, "RUN CONTROL PARAMETERS");
1863     ir->eI = get_eeenum(&inp, "integrator",         ei_names, wi);
1864     printStringNoNewline(&inp, "Start time and timestep in ps");
1865     ir->init_t  = get_ereal(&inp, "tinit", 0.0, wi);
1866     ir->delta_t = get_ereal(&inp, "dt",    0.001, wi);
1867     ir->nsteps  = get_eint64(&inp, "nsteps",     0, wi);
1868     printStringNoNewline(&inp, "For exact run continuation or redoing part of a run");
1869     ir->init_step = get_eint64(&inp, "init-step",  0, wi);
1870     printStringNoNewline(&inp, "Part index is updated automatically on checkpointing (keeps files separate)");
1871     ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
1872     printStringNoNewline(&inp, "mode for center of mass motion removal");
1873     ir->comm_mode = get_eeenum(&inp, "comm-mode",  ecm_names, wi);
1874     printStringNoNewline(&inp, "number of steps for center of mass motion removal");
1875     ir->nstcomm = get_eint(&inp, "nstcomm",    100, wi);
1876     printStringNoNewline(&inp, "group(s) for center of mass motion removal");
1877     setStringEntry(&inp, "comm-grps",   is->vcm,            nullptr);
1878
1879     printStringNewline(&inp, "LANGEVIN DYNAMICS OPTIONS");
1880     printStringNoNewline(&inp, "Friction coefficient (amu/ps) and random seed");
1881     ir->bd_fric = get_ereal(&inp, "bd-fric",    0.0, wi);
1882     ir->ld_seed = get_eint64(&inp, "ld-seed",    -1, wi);
1883
1884     /* Em stuff */
1885     printStringNewline(&inp, "ENERGY MINIMIZATION OPTIONS");
1886     printStringNoNewline(&inp, "Force tolerance and initial step-size");
1887     ir->em_tol      = get_ereal(&inp, "emtol",     10.0, wi);
1888     ir->em_stepsize = get_ereal(&inp, "emstep", 0.01, wi);
1889     printStringNoNewline(&inp, "Max number of iterations in relax-shells");
1890     ir->niter = get_eint(&inp, "niter",      20, wi);
1891     printStringNoNewline(&inp, "Step size (ps^2) for minimization of flexible constraints");
1892     ir->fc_stepsize = get_ereal(&inp, "fcstep", 0, wi);
1893     printStringNoNewline(&inp, "Frequency of steepest descents steps when doing CG");
1894     ir->nstcgsteep = get_eint(&inp, "nstcgsteep", 1000, wi);
1895     ir->nbfgscorr  = get_eint(&inp, "nbfgscorr",  10, wi);
1896
1897     printStringNewline(&inp, "TEST PARTICLE INSERTION OPTIONS");
1898     ir->rtpi = get_ereal(&inp, "rtpi",   0.05, wi);
1899
1900     /* Output options */
1901     printStringNewline(&inp, "OUTPUT CONTROL OPTIONS");
1902     printStringNoNewline(&inp, "Output frequency for coords (x), velocities (v) and forces (f)");
1903     ir->nstxout = get_eint(&inp, "nstxout",    0, wi);
1904     ir->nstvout = get_eint(&inp, "nstvout",    0, wi);
1905     ir->nstfout = get_eint(&inp, "nstfout",    0, wi);
1906     printStringNoNewline(&inp, "Output frequency for energies to log file and energy file");
1907     ir->nstlog        = get_eint(&inp, "nstlog", 1000, wi);
1908     ir->nstcalcenergy = get_eint(&inp, "nstcalcenergy", 100, wi);
1909     ir->nstenergy     = get_eint(&inp, "nstenergy",  1000, wi);
1910     printStringNoNewline(&inp, "Output frequency and precision for .xtc file");
1911     ir->nstxout_compressed      = get_eint(&inp, "nstxout-compressed",  0, wi);
1912     ir->x_compression_precision = get_ereal(&inp, "compressed-x-precision", 1000.0, wi);
1913     printStringNoNewline(&inp, "This selects the subset of atoms for the compressed");
1914     printStringNoNewline(&inp, "trajectory file. You can select multiple groups. By");
1915     printStringNoNewline(&inp, "default, all atoms will be written.");
1916     setStringEntry(&inp, "compressed-x-grps", is->x_compressed_groups, nullptr);
1917     printStringNoNewline(&inp, "Selection of energy groups");
1918     setStringEntry(&inp, "energygrps",  is->energy,         nullptr);
1919
1920     /* Neighbor searching */
1921     printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
1922     printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)");
1923     ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme",    ecutscheme_names, wi);
1924     printStringNoNewline(&inp, "nblist update frequency");
1925     ir->nstlist = get_eint(&inp, "nstlist",    10, wi);
1926     printStringNoNewline(&inp, "ns algorithm (simple or grid)");
1927     ir->ns_type = get_eeenum(&inp, "ns-type",    ens_names, wi);
1928     printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
1929     ir->ePBC          = get_eeenum(&inp, "pbc",       epbc_names, wi);
1930     ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0;
1931     printStringNoNewline(&inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
1932     printStringNoNewline(&inp, "a value of -1 means: use rlist");
1933     ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance",    0.005, wi);
1934     printStringNoNewline(&inp, "nblist cut-off");
1935     ir->rlist = get_ereal(&inp, "rlist",  1.0, wi);
1936     printStringNoNewline(&inp, "long-range cut-off for switched potentials");
1937
1938     /* Electrostatics */
1939     printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
1940     printStringNoNewline(&inp, "Method for doing electrostatics");
1941     ir->coulombtype      = get_eeenum(&inp, "coulombtype",    eel_names, wi);
1942     ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier",    eintmod_names, wi);
1943     printStringNoNewline(&inp, "cut-off lengths");
1944     ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch",    0.0, wi);
1945     ir->rcoulomb        = get_ereal(&inp, "rcoulomb",   1.0, wi);
1946     printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
1947     ir->epsilon_r  = get_ereal(&inp, "epsilon-r",  1.0, wi);
1948     ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
1949     printStringNoNewline(&inp, "Method for doing Van der Waals");
1950     ir->vdwtype      = get_eeenum(&inp, "vdw-type",    evdw_names, wi);
1951     ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier",    eintmod_names, wi);
1952     printStringNoNewline(&inp, "cut-off lengths");
1953     ir->rvdw_switch = get_ereal(&inp, "rvdw-switch",    0.0, wi);
1954     ir->rvdw        = get_ereal(&inp, "rvdw",   1.0, wi);
1955     printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
1956     ir->eDispCorr = get_eeenum(&inp, "DispCorr",  edispc_names, wi);
1957     printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
1958     ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
1959     printStringNoNewline(&inp, "Separate tables between energy group pairs");
1960     setStringEntry(&inp, "energygrp-table", is->egptable,   nullptr);
1961     printStringNoNewline(&inp, "Spacing for the PME/PPPM FFT grid");
1962     ir->fourier_spacing = get_ereal(&inp, "fourierspacing", 0.12, wi);
1963     printStringNoNewline(&inp, "FFT grid size, when a value is 0 fourierspacing will be used");
1964     ir->nkx = get_eint(&inp, "fourier-nx",         0, wi);
1965     ir->nky = get_eint(&inp, "fourier-ny",         0, wi);
1966     ir->nkz = get_eint(&inp, "fourier-nz",         0, wi);
1967     printStringNoNewline(&inp, "EWALD/PME/PPPM parameters");
1968     ir->pme_order              = get_eint(&inp, "pme-order",   4, wi);
1969     ir->ewald_rtol             = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
1970     ir->ewald_rtol_lj          = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
1971     ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
1972     ir->ewald_geometry         = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
1973     ir->epsilon_surface        = get_ereal(&inp, "epsilon-surface", 0.0, wi);
1974
1975     /* Implicit solvation is no longer supported, but we need grompp
1976        to be able to refuse old .mdp files that would have built a tpr
1977        to run it. Thus, only "no" is accepted. */
1978     ir->implicit_solvent = (get_eeenum(&inp, "implicit-solvent", no_names, wi) != 0);
1979
1980     /* Coupling stuff */
1981     printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
1982     printStringNoNewline(&inp, "Temperature coupling");
1983     ir->etc                = get_eeenum(&inp, "tcoupl",        etcoupl_names, wi);
1984     ir->nsttcouple         = get_eint(&inp, "nsttcouple",  -1, wi);
1985     ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
1986     ir->bPrintNHChains     = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
1987     printStringNoNewline(&inp, "Groups to couple separately");
1988     setStringEntry(&inp, "tc-grps",     is->tcgrps,         nullptr);
1989     printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
1990     setStringEntry(&inp, "tau-t",   is->tau_t,      nullptr);
1991     setStringEntry(&inp, "ref-t",   is->ref_t,      nullptr);
1992     printStringNoNewline(&inp, "pressure coupling");
1993     ir->epc        = get_eeenum(&inp, "pcoupl",        epcoupl_names, wi);
1994     ir->epct       = get_eeenum(&inp, "pcoupltype",       epcoupltype_names, wi);
1995     ir->nstpcouple = get_eint(&inp, "nstpcouple",  -1, wi);
1996     printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
1997     ir->tau_p = get_ereal(&inp, "tau-p",  1.0, wi);
1998     setStringEntry(&inp, "compressibility", dumstr[0],  nullptr);
1999     setStringEntry(&inp, "ref-p",       dumstr[1],      nullptr);
2000     printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
2001     ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
2002
2003     /* QMMM */
2004     printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
2005     ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0);
2006     printStringNoNewline(&inp, "Groups treated Quantum Mechanically");
2007     setStringEntry(&inp, "QMMM-grps",  is->QMMM,          nullptr);
2008     printStringNoNewline(&inp, "QM method");
2009     setStringEntry(&inp, "QMmethod",     is->QMmethod, nullptr);
2010     printStringNoNewline(&inp, "QMMM scheme");
2011     ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme",    eQMMMscheme_names, wi);
2012     printStringNoNewline(&inp, "QM basisset");
2013     setStringEntry(&inp, "QMbasis",      is->QMbasis, nullptr);
2014     printStringNoNewline(&inp, "QM charge");
2015     setStringEntry(&inp, "QMcharge",    is->QMcharge, nullptr);
2016     printStringNoNewline(&inp, "QM multiplicity");
2017     setStringEntry(&inp, "QMmult",      is->QMmult, nullptr);
2018     printStringNoNewline(&inp, "Surface Hopping");
2019     setStringEntry(&inp, "SH",          is->bSH, nullptr);
2020     printStringNoNewline(&inp, "CAS space options");
2021     setStringEntry(&inp, "CASorbitals",      is->CASorbitals,   nullptr);
2022     setStringEntry(&inp, "CASelectrons",     is->CASelectrons,  nullptr);
2023     setStringEntry(&inp, "SAon", is->SAon, nullptr);
2024     setStringEntry(&inp, "SAoff", is->SAoff, nullptr);
2025     setStringEntry(&inp, "SAsteps", is->SAsteps, nullptr);
2026     printStringNoNewline(&inp, "Scale factor for MM charges");
2027     ir->scalefactor = get_ereal(&inp, "MMChargeScaleFactor", 1.0, wi);
2028
2029     /* Simulated annealing */
2030     printStringNewline(&inp, "SIMULATED ANNEALING");
2031     printStringNoNewline(&inp, "Type of annealing for each temperature group (no/single/periodic)");
2032     setStringEntry(&inp, "annealing",   is->anneal,      nullptr);
2033     printStringNoNewline(&inp, "Number of time points to use for specifying annealing in each group");
2034     setStringEntry(&inp, "annealing-npoints", is->anneal_npoints, nullptr);
2035     printStringNoNewline(&inp, "List of times at the annealing points for each group");
2036     setStringEntry(&inp, "annealing-time",       is->anneal_time,       nullptr);
2037     printStringNoNewline(&inp, "Temp. at each annealing point, for each group.");
2038     setStringEntry(&inp, "annealing-temp",  is->anneal_temp,  nullptr);
2039
2040     /* Startup run */
2041     printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
2042     opts->bGenVel = (get_eeenum(&inp, "gen-vel",  yesno_names, wi) != 0);
2043     opts->tempi   = get_ereal(&inp, "gen-temp",    300.0, wi);
2044     opts->seed    = get_eint(&inp, "gen-seed",     -1, wi);
2045
2046     /* Shake stuff */
2047     printStringNewline(&inp, "OPTIONS FOR BONDS");
2048     opts->nshake = get_eeenum(&inp, "constraints",   constraints, wi);
2049     printStringNoNewline(&inp, "Type of constraint algorithm");
2050     ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
2051     printStringNoNewline(&inp, "Do not constrain the start configuration");
2052     ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0);
2053     printStringNoNewline(&inp, "Use successive overrelaxation to reduce the number of shake iterations");
2054     ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0);
2055     printStringNoNewline(&inp, "Relative tolerance of shake");
2056     ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
2057     printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
2058     ir->nProjOrder = get_eint(&inp, "lincs-order", 4, wi);
2059     printStringNoNewline(&inp, "Number of iterations in the final step of LINCS. 1 is fine for");
2060     printStringNoNewline(&inp, "normal simulations, but use 2 to conserve energy in NVE runs.");
2061     printStringNoNewline(&inp, "For energy minimization with constraints it should be 4 to 8.");
2062     ir->nLincsIter = get_eint(&inp, "lincs-iter", 1, wi);
2063     printStringNoNewline(&inp, "Lincs will write a warning to the stderr if in one step a bond");
2064     printStringNoNewline(&inp, "rotates over more degrees than");
2065     ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
2066     printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
2067     opts->bMorse = (get_eeenum(&inp, "morse", yesno_names, wi) != 0);
2068
2069     /* Energy group exclusions */
2070     printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
2071     printStringNoNewline(&inp, "Pairs of energy groups for which all non-bonded interactions are excluded");
2072     setStringEntry(&inp, "energygrp-excl", is->egpexcl,     nullptr);
2073
2074     /* Walls */
2075     printStringNewline(&inp, "WALLS");
2076     printStringNoNewline(&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
2077     ir->nwall         = get_eint(&inp, "nwall", 0, wi);
2078     ir->wall_type     = get_eeenum(&inp, "wall-type",   ewt_names, wi);
2079     ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
2080     setStringEntry(&inp, "wall-atomtype", is->wall_atomtype, nullptr);
2081     setStringEntry(&inp, "wall-density",  is->wall_density,  nullptr);
2082     ir->wall_ewald_zfac = get_ereal(&inp, "wall-ewald-zfac", 3, wi);
2083
2084     /* COM pulling */
2085     printStringNewline(&inp, "COM PULLING");
2086     ir->bPull = (get_eeenum(&inp, "pull", yesno_names, wi) != 0);
2087     if (ir->bPull)
2088     {
2089         snew(ir->pull, 1);
2090         is->pull_grp = read_pullparams(&inp, ir->pull, wi);
2091     }
2092
2093     /* AWH biasing
2094        NOTE: needs COM pulling input */
2095     printStringNewline(&inp, "AWH biasing");
2096     ir->bDoAwh = (get_eeenum(&inp, "awh", yesno_names, wi) != 0);
2097     if (ir->bDoAwh)
2098     {
2099         if (ir->bPull)
2100         {
2101             ir->awhParams = gmx::readAndCheckAwhParams(&inp, ir, wi);
2102         }
2103         else
2104         {
2105             gmx_fatal(FARGS, "AWH biasing is only compatible with COM pulling turned on");
2106         }
2107     }
2108
2109     /* Enforced rotation */
2110     printStringNewline(&inp, "ENFORCED ROTATION");
2111     printStringNoNewline(&inp, "Enforced rotation: No or Yes");
2112     ir->bRot = (get_eeenum(&inp, "rotation", yesno_names, wi) != 0);
2113     if (ir->bRot)
2114     {
2115         snew(ir->rot, 1);
2116         is->rot_grp = read_rotparams(&inp, ir->rot, wi);
2117     }
2118
2119     /* Interactive MD */
2120     ir->bIMD = FALSE;
2121     printStringNewline(&inp, "Group to display and/or manipulate in interactive MD session");
2122     setStringEntry(&inp, "IMD-group", is->imd_grp, nullptr);
2123     if (is->imd_grp[0] != '\0')
2124     {
2125         snew(ir->imd, 1);
2126         ir->bIMD = TRUE;
2127     }
2128
2129     /* Refinement */
2130     printStringNewline(&inp, "NMR refinement stuff");
2131     printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
2132     ir->eDisre = get_eeenum(&inp, "disre",     edisre_names, wi);
2133     printStringNoNewline(&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
2134     ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
2135     printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
2136     ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0);
2137     ir->dr_fc       = get_ereal(&inp, "disre-fc",  1000.0, wi);
2138     ir->dr_tau      = get_ereal(&inp, "disre-tau", 0.0, wi);
2139     printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
2140     ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
2141     printStringNoNewline(&inp, "Orientation restraints: No or Yes");
2142     opts->bOrire = (get_eeenum(&inp, "orire",   yesno_names, wi) != 0);
2143     printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
2144     ir->orires_fc  = get_ereal(&inp, "orire-fc",  0.0, wi);
2145     ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
2146     setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp,    nullptr);
2147     printStringNoNewline(&inp, "Output frequency for trace(SD) and S to energy file");
2148     ir->nstorireout = get_eint(&inp, "nstorireout", 100, wi);
2149
2150     /* free energy variables */
2151     printStringNewline(&inp, "Free energy variables");
2152     ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
2153     setStringEntry(&inp, "couple-moltype",  is->couple_moltype,  nullptr);
2154     opts->couple_lam0  = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
2155     opts->couple_lam1  = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
2156     opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0);
2157
2158     fep->init_lambda    = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
2159                                                                             we can recognize if
2160                                                                             it was not entered */
2161     fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
2162     fep->delta_lambda   = get_ereal(&inp, "delta-lambda", 0.0, wi);
2163     fep->nstdhdl        = get_eint(&inp, "nstdhdl", 50, wi);
2164     setStringEntry(&inp, "fep-lambdas", is->fep_lambda[efptFEP], nullptr);
2165     setStringEntry(&inp, "mass-lambdas", is->fep_lambda[efptMASS], nullptr);
2166     setStringEntry(&inp, "coul-lambdas", is->fep_lambda[efptCOUL], nullptr);
2167     setStringEntry(&inp, "vdw-lambdas", is->fep_lambda[efptVDW], nullptr);
2168     setStringEntry(&inp, "bonded-lambdas", is->fep_lambda[efptBONDED], nullptr);
2169     setStringEntry(&inp, "restraint-lambdas", is->fep_lambda[efptRESTRAINT], nullptr);
2170     setStringEntry(&inp, "temperature-lambdas", is->fep_lambda[efptTEMPERATURE], nullptr);
2171     fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
2172     setStringEntry(&inp, "init-lambda-weights", is->lambda_weights, nullptr);
2173     fep->edHdLPrintEnergy   = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
2174     fep->sc_alpha           = get_ereal(&inp, "sc-alpha", 0.0, wi);
2175     fep->sc_power           = get_eint(&inp, "sc-power", 1, wi);
2176     fep->sc_r_power         = get_ereal(&inp, "sc-r-power", 6.0, wi);
2177     fep->sc_sigma           = get_ereal(&inp, "sc-sigma", 0.3, wi);
2178     fep->bScCoul            = (get_eeenum(&inp, "sc-coul", yesno_names, wi) != 0);
2179     fep->dh_hist_size       = get_eint(&inp, "dh_hist_size", 0, wi);
2180     fep->dh_hist_spacing    = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2181     fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
2182     fep->dhdl_derivatives   = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
2183     fep->dh_hist_size       = get_eint(&inp, "dh_hist_size", 0, wi);
2184     fep->dh_hist_spacing    = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2185
2186     /* Non-equilibrium MD stuff */
2187     printStringNewline(&inp, "Non-equilibrium MD stuff");
2188     setStringEntry(&inp, "acc-grps",    is->accgrps,        nullptr);
2189     setStringEntry(&inp, "accelerate",  is->acc,            nullptr);
2190     setStringEntry(&inp, "freezegrps",  is->freeze,         nullptr);
2191     setStringEntry(&inp, "freezedim",   is->frdim,          nullptr);
2192     ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
2193     setStringEntry(&inp, "deform",      is->deform,         nullptr);
2194
2195     /* simulated tempering variables */
2196     printStringNewline(&inp, "simulated tempering variables");
2197     ir->bSimTemp                   = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0);
2198     ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
2199     ir->simtempvals->simtemp_low   = get_ereal(&inp, "sim-temp-low", 300.0, wi);
2200     ir->simtempvals->simtemp_high  = get_ereal(&inp, "sim-temp-high", 300.0, wi);
2201
2202     /* expanded ensemble variables */
2203     if (ir->efep == efepEXPANDED || ir->bSimTemp)
2204     {
2205         read_expandedparams(&inp, expand, wi);
2206     }
2207
2208     /* Electric fields */
2209     {
2210         gmx::KeyValueTreeObject      convertedValues = flatKeyValueTreeFromInpFile(inp);
2211         gmx::KeyValueTreeTransformer transform;
2212         transform.rules()->addRule()
2213             .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
2214         mdModules->initMdpTransform(transform.rules());
2215         for (const auto &path : transform.mappedPaths())
2216         {
2217             GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
2218             mark_einp_set(inp, path[0].c_str());
2219         }
2220         MdpErrorHandler              errorHandler(wi);
2221         auto                         result
2222                    = transform.transform(convertedValues, &errorHandler);
2223         ir->params = new gmx::KeyValueTreeObject(result.object());
2224         mdModules->adjustInputrecBasedOnModules(ir);
2225         errorHandler.setBackMapping(result.backMapping());
2226         mdModules->assignOptionsToModules(*ir->params, &errorHandler);
2227     }
2228
2229     /* Ion/water position swapping ("computational electrophysiology") */
2230     printStringNewline(&inp, "Ion/water position swapping for computational electrophysiology setups");
2231     printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
2232     ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
2233     if (ir->eSwapCoords != eswapNO)
2234     {
2235         char buf[STRLEN];
2236         int  nIonTypes;
2237
2238
2239         snew(ir->swap, 1);
2240         printStringNoNewline(&inp, "Swap attempt frequency");
2241         ir->swap->nstswap = get_eint(&inp, "swap-frequency", 1, wi);
2242         printStringNoNewline(&inp, "Number of ion types to be controlled");
2243         nIonTypes = get_eint(&inp, "iontypes", 1, wi);
2244         if (nIonTypes < 1)
2245         {
2246             warning_error(wi, "You need to provide at least one ion type for position exchanges.");
2247         }
2248         ir->swap->ngrp = nIonTypes + eSwapFixedGrpNR;
2249         snew(ir->swap->grp, ir->swap->ngrp);
2250         for (i = 0; i < ir->swap->ngrp; i++)
2251         {
2252             snew(ir->swap->grp[i].molname, STRLEN);
2253         }
2254         printStringNoNewline(&inp, "Two index groups that contain the compartment-partitioning atoms");
2255         setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
2256         setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
2257         printStringNoNewline(&inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used");
2258         ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0);
2259         ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0);
2260
2261         printStringNoNewline(&inp, "Name of solvent molecules");
2262         setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
2263
2264         printStringNoNewline(&inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)");
2265         printStringNoNewline(&inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,");
2266         printStringNoNewline(&inp, "however, if correctly defined, the permeation events are recorded per channel");
2267         ir->swap->cyl0r = get_ereal(&inp, "cyl0-r", 2.0, wi);
2268         ir->swap->cyl0u = get_ereal(&inp, "cyl0-up", 1.0, wi);
2269         ir->swap->cyl0l = get_ereal(&inp, "cyl0-down", 1.0, wi);
2270         ir->swap->cyl1r = get_ereal(&inp, "cyl1-r", 2.0, wi);
2271         ir->swap->cyl1u = get_ereal(&inp, "cyl1-up", 1.0, wi);
2272         ir->swap->cyl1l = get_ereal(&inp, "cyl1-down", 1.0, wi);
2273
2274         printStringNoNewline(&inp, "Average the number of ions per compartment over these many swap attempt steps");
2275         ir->swap->nAverage = get_eint(&inp, "coupl-steps", 10, wi);
2276
2277         printStringNoNewline(&inp, "Names of the ion types that can be exchanged with solvent molecules,");
2278         printStringNoNewline(&inp, "and the requested number of ions of this type in compartments A and B");
2279         printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
2280         for (i = 0; i < nIonTypes; i++)
2281         {
2282             int ig = eSwapFixedGrpNR + i;
2283
2284             sprintf(buf, "iontype%d-name", i);
2285             setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
2286             sprintf(buf, "iontype%d-in-A", i);
2287             ir->swap->grp[ig].nmolReq[0] = get_eint(&inp, buf, -1, wi);
2288             sprintf(buf, "iontype%d-in-B", i);
2289             ir->swap->grp[ig].nmolReq[1] = get_eint(&inp, buf, -1, wi);
2290         }
2291
2292         printStringNoNewline(&inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
2293         printStringNoNewline(&inp, "at maximum distance (= bulk concentration) to the split group layers. However,");
2294         printStringNoNewline(&inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
2295         printStringNoNewline(&inp, "towards one of the compartment-partitioning layers (at +/- 1.0).");
2296         ir->swap->bulkOffset[0] = get_ereal(&inp, "bulk-offsetA", 0.0, wi);
2297         ir->swap->bulkOffset[1] = get_ereal(&inp, "bulk-offsetB", 0.0, wi);
2298         if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0)
2299             || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) )
2300         {
2301             warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !");
2302         }
2303
2304         printStringNoNewline(&inp, "Start to swap ions if threshold difference to requested count is reached");
2305         ir->swap->threshold = get_ereal(&inp, "threshold", 1.0, wi);
2306     }
2307
2308     /* AdResS is no longer supported, but we need grompp to be able to
2309        refuse to process old .mdp files that used it. */
2310     ir->bAdress = (get_eeenum(&inp, "adress", no_names, wi) != 0);
2311
2312     /* User defined thingies */
2313     printStringNewline(&inp, "User defined thingies");
2314     setStringEntry(&inp, "user1-grps",  is->user1,          nullptr);
2315     setStringEntry(&inp, "user2-grps",  is->user2,          nullptr);
2316     ir->userint1  = get_eint(&inp, "userint1",   0, wi);
2317     ir->userint2  = get_eint(&inp, "userint2",   0, wi);
2318     ir->userint3  = get_eint(&inp, "userint3",   0, wi);
2319     ir->userint4  = get_eint(&inp, "userint4",   0, wi);
2320     ir->userreal1 = get_ereal(&inp, "userreal1",  0, wi);
2321     ir->userreal2 = get_ereal(&inp, "userreal2",  0, wi);
2322     ir->userreal3 = get_ereal(&inp, "userreal3",  0, wi);
2323     ir->userreal4 = get_ereal(&inp, "userreal4",  0, wi);
2324 #undef CTYPE
2325
2326     {
2327         gmx::TextOutputFile stream(mdparout);
2328         write_inpfile(&stream, mdparout, &inp, FALSE, writeMdpHeader, wi);
2329
2330         // Transform module data into a flat key-value tree for output.
2331         gmx::KeyValueTreeBuilder       builder;
2332         gmx::KeyValueTreeObjectBuilder builderObject = builder.rootObject();
2333         mdModules->buildMdpOutput(&builderObject);
2334         {
2335             gmx::TextWriter writer(&stream);
2336             writeKeyValueTreeAsMdp(&writer, builder.build());
2337         }
2338         stream.close();
2339     }
2340
2341     /* Process options if necessary */
2342     for (m = 0; m < 2; m++)
2343     {
2344         for (i = 0; i < 2*DIM; i++)
2345         {
2346             dumdub[m][i] = 0.0;
2347         }
2348         if (ir->epc)
2349         {
2350             switch (ir->epct)
2351             {
2352                 case epctISOTROPIC:
2353                     if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1)
2354                     {
2355                         warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 1)");
2356                     }
2357                     dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX];
2358                     break;
2359                 case epctSEMIISOTROPIC:
2360                 case epctSURFACETENSION:
2361                     if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2)
2362                     {
2363                         warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 2)");
2364                     }
2365                     dumdub[m][YY] = dumdub[m][XX];
2366                     break;
2367                 case epctANISOTROPIC:
2368                     if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf",
2369                                &(dumdub[m][XX]), &(dumdub[m][YY]), &(dumdub[m][ZZ]),
2370                                &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5])) != 6)
2371                     {
2372                         warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 6)");
2373                     }
2374                     break;
2375                 default:
2376                     gmx_fatal(FARGS, "Pressure coupling type %s not implemented yet",
2377                               epcoupltype_names[ir->epct]);
2378             }
2379         }
2380     }
2381     clear_mat(ir->ref_p);
2382     clear_mat(ir->compress);
2383     for (i = 0; i < DIM; i++)
2384     {
2385         ir->ref_p[i][i]    = dumdub[1][i];
2386         ir->compress[i][i] = dumdub[0][i];
2387     }
2388     if (ir->epct == epctANISOTROPIC)
2389     {
2390         ir->ref_p[XX][YY] = dumdub[1][3];
2391         ir->ref_p[XX][ZZ] = dumdub[1][4];
2392         ir->ref_p[YY][ZZ] = dumdub[1][5];
2393         if (ir->ref_p[XX][YY] != 0 && ir->ref_p[XX][ZZ] != 0 && ir->ref_p[YY][ZZ] != 0)
2394         {
2395             warning(wi, "All off-diagonal reference pressures are non-zero. Are you sure you want to apply a threefold shear stress?\n");
2396         }
2397         ir->compress[XX][YY] = dumdub[0][3];
2398         ir->compress[XX][ZZ] = dumdub[0][4];
2399         ir->compress[YY][ZZ] = dumdub[0][5];
2400         for (i = 0; i < DIM; i++)
2401         {
2402             for (m = 0; m < i; m++)
2403             {
2404                 ir->ref_p[i][m]    = ir->ref_p[m][i];
2405                 ir->compress[i][m] = ir->compress[m][i];
2406             }
2407         }
2408     }
2409
2410     if (ir->comm_mode == ecmNO)
2411     {
2412         ir->nstcomm = 0;
2413     }
2414
2415     opts->couple_moltype = nullptr;
2416     if (strlen(is->couple_moltype) > 0)
2417     {
2418         if (ir->efep != efepNO)
2419         {
2420             opts->couple_moltype = gmx_strdup(is->couple_moltype);
2421             if (opts->couple_lam0 == opts->couple_lam1)
2422             {
2423                 warning(wi, "The lambda=0 and lambda=1 states for coupling are identical");
2424             }
2425             if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE ||
2426                                    opts->couple_lam1 == ecouplamNONE))
2427             {
2428                 warning(wi, "For proper sampling of the (nearly) decoupled state, stochastic dynamics should be used");
2429             }
2430         }
2431         else
2432         {
2433             warning_note(wi, "Free energy is turned off, so we will not decouple the molecule listed in your input.");
2434         }
2435     }
2436     /* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */
2437     if (ir->efep != efepNO)
2438     {
2439         if (fep->delta_lambda > 0)
2440         {
2441             ir->efep = efepSLOWGROWTH;
2442         }
2443     }
2444
2445     if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES)
2446     {
2447         fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2448         warning_note(wi, "Old option for dhdl-print-energy given: "
2449                      "changing \"yes\" to \"total\"\n");
2450     }
2451
2452     if (ir->bSimTemp && (fep->edHdLPrintEnergy == edHdLPrintEnergyNO))
2453     {
2454         /* always print out the energy to dhdl if we are doing
2455            expanded ensemble, since we need the total energy for
2456            analysis if the temperature is changing. In some
2457            conditions one may only want the potential energy, so
2458            we will allow that if the appropriate mdp setting has
2459            been enabled. Otherwise, total it is:
2460          */
2461         fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2462     }
2463
2464     if ((ir->efep != efepNO) || ir->bSimTemp)
2465     {
2466         ir->bExpanded = FALSE;
2467         if ((ir->efep == efepEXPANDED) || ir->bSimTemp)
2468         {
2469             ir->bExpanded = TRUE;
2470         }
2471         do_fep_params(ir, is->fep_lambda, is->lambda_weights, wi);
2472         if (ir->bSimTemp) /* done after fep params */
2473         {
2474             do_simtemp_params(ir);
2475         }
2476
2477         /* Because sc-coul (=FALSE by default) only acts on the lambda state
2478          * setup and not on the old way of specifying the free-energy setup,
2479          * we should check for using soft-core when not needed, since that
2480          * can complicate the sampling significantly.
2481          * Note that we only check for the automated coupling setup.
2482          * If the (advanced) user does FEP through manual topology changes,
2483          * this check will not be triggered.
2484          */
2485         if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 &&
2486             ir->fepvals->sc_alpha != 0 &&
2487             (couple_lambda_has_vdw_on(opts->couple_lam0) &&
2488              couple_lambda_has_vdw_on(opts->couple_lam1)))
2489         {
2490             warning(wi, "You are using soft-core interactions while the Van der Waals interactions are not decoupled (note that the sc-coul option is only active when using lambda states). Although this will not lead to errors, you will need much more sampling than without soft-core interactions. Consider using sc-alpha=0.");
2491         }
2492     }
2493     else
2494     {
2495         ir->fepvals->n_lambda = 0;
2496     }
2497
2498     /* WALL PARAMETERS */
2499
2500     do_wall_params(ir, is->wall_atomtype, is->wall_density, opts, wi);
2501
2502     /* ORIENTATION RESTRAINT PARAMETERS */
2503
2504     if (opts->bOrire && gmx::splitString(is->orirefitgrp).size() != 1)
2505     {
2506         warning_error(wi, "ERROR: Need one orientation restraint fit group\n");
2507     }
2508
2509     /* DEFORMATION PARAMETERS */
2510
2511     clear_mat(ir->deform);
2512     for (i = 0; i < 6; i++)
2513     {
2514         dumdub[0][i] = 0;
2515     }
2516
2517     double gmx_unused canary;
2518     int               ndeform = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf %lf",
2519                                        &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]),
2520                                        &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]), &canary);
2521
2522     if (strlen(is->deform) > 0 && ndeform != 6)
2523     {
2524         warning_error(wi, gmx::formatString("Cannot parse exactly 6 box deformation velocities from string '%s'", is->deform).c_str());
2525     }
2526     for (i = 0; i < 3; i++)
2527     {
2528         ir->deform[i][i] = dumdub[0][i];
2529     }
2530     ir->deform[YY][XX] = dumdub[0][3];
2531     ir->deform[ZZ][XX] = dumdub[0][4];
2532     ir->deform[ZZ][YY] = dumdub[0][5];
2533     if (ir->epc != epcNO)
2534     {
2535         for (i = 0; i < 3; i++)
2536         {
2537             for (j = 0; j <= i; j++)
2538             {
2539                 if (ir->deform[i][j] != 0 && ir->compress[i][j] != 0)
2540                 {
2541                     warning_error(wi, "A box element has deform set and compressibility > 0");
2542                 }
2543             }
2544         }
2545         for (i = 0; i < 3; i++)
2546         {
2547             for (j = 0; j < i; j++)
2548             {
2549                 if (ir->deform[i][j] != 0)
2550                 {
2551                     for (m = j; m < DIM; m++)
2552                     {
2553                         if (ir->compress[m][j] != 0)
2554                         {
2555                             sprintf(warn_buf, "An off-diagonal box element has deform set while compressibility > 0 for the same component of another box vector, this might lead to spurious periodicity effects.");
2556                             warning(wi, warn_buf);
2557                         }
2558                     }
2559                 }
2560             }
2561         }
2562     }
2563
2564     /* Ion/water position swapping checks */
2565     if (ir->eSwapCoords != eswapNO)
2566     {
2567         if (ir->swap->nstswap < 1)
2568         {
2569             warning_error(wi, "swap_frequency must be 1 or larger when ion swapping is requested");
2570         }
2571         if (ir->swap->nAverage < 1)
2572         {
2573             warning_error(wi, "coupl_steps must be 1 or larger.\n");
2574         }
2575         if (ir->swap->threshold < 1.0)
2576         {
2577             warning_error(wi, "Ion count threshold must be at least 1.\n");
2578         }
2579     }
2580
2581     sfree(dumstr[0]);
2582     sfree(dumstr[1]);
2583 }
2584
2585 static int search_QMstring(const char *s, int ng, const char *gn[])
2586 {
2587     /* same as normal search_string, but this one searches QM strings */
2588     int i;
2589
2590     for (i = 0; (i < ng); i++)
2591     {
2592         if (gmx_strcasecmp(s, gn[i]) == 0)
2593         {
2594             return i;
2595         }
2596     }
2597
2598     gmx_fatal(FARGS, "this QM method or basisset (%s) is not implemented\n!", s);
2599 } /* search_QMstring */
2600
2601 /* We would like gn to be const as well, but C doesn't allow this */
2602 /* TODO this is utility functionality (search for the index of a
2603    string in a collection), so should be refactored and located more
2604    centrally. */
2605 int search_string(const char *s, int ng, char *gn[])
2606 {
2607     int i;
2608
2609     for (i = 0; (i < ng); i++)
2610     {
2611         if (gmx_strcasecmp(s, gn[i]) == 0)
2612         {
2613             return i;
2614         }
2615     }
2616
2617     gmx_fatal(FARGS,
2618               "Group %s referenced in the .mdp file was not found in the index file.\n"
2619               "Group names must match either [moleculetype] names or custom index group\n"
2620               "names, in which case you must supply an index file to the '-n' option\n"
2621               "of grompp.",
2622               s);
2623 }
2624
2625 static bool do_numbering(int natoms, gmx_groups_t *groups,
2626                          gmx::ArrayRef<std::string> groupsFromMdpFile,
2627                          t_blocka *block, char *gnames[],
2628                          int gtype, int restnm,
2629                          int grptp, bool bVerbose,
2630                          warninp_t wi)
2631 {
2632     unsigned short *cbuf;
2633     t_grps         *grps = &(groups->grps[gtype]);
2634     int             j, gid, aj, ognr, ntot = 0;
2635     const char     *title;
2636     bool            bRest;
2637     char            warn_buf[STRLEN];
2638
2639     title = gtypes[gtype];
2640
2641     snew(cbuf, natoms);
2642     /* Mark all id's as not set */
2643     for (int i = 0; (i < natoms); i++)
2644     {
2645         cbuf[i] = NOGID;
2646     }
2647
2648     snew(grps->nm_ind, groupsFromMdpFile.size()+1); /* +1 for possible rest group */
2649     for (int i = 0; i != groupsFromMdpFile.size(); ++i)
2650     {
2651         /* Lookup the group name in the block structure */
2652         gid = search_string(groupsFromMdpFile[i].c_str(), block->nr, gnames);
2653         if ((grptp != egrptpONE) || (i == 0))
2654         {
2655             grps->nm_ind[grps->nr++] = gid;
2656         }
2657
2658         /* Now go over the atoms in the group */
2659         for (j = block->index[gid]; (j < block->index[gid+1]); j++)
2660         {
2661
2662             aj = block->a[j];
2663
2664             /* Range checking */
2665             if ((aj < 0) || (aj >= natoms))
2666             {
2667                 gmx_fatal(FARGS, "Invalid atom number %d in indexfile", aj);
2668             }
2669             /* Lookup up the old group number */
2670             ognr = cbuf[aj];
2671             if (ognr != NOGID)
2672             {
2673                 gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)",
2674                           aj+1, title, ognr+1, i+1);
2675             }
2676             else
2677             {
2678                 /* Store the group number in buffer */
2679                 if (grptp == egrptpONE)
2680                 {
2681                     cbuf[aj] = 0;
2682                 }
2683                 else
2684                 {
2685                     cbuf[aj] = i;
2686                 }
2687                 ntot++;
2688             }
2689         }
2690     }
2691
2692     /* Now check whether we have done all atoms */
2693     bRest = FALSE;
2694     if (ntot != natoms)
2695     {
2696         if (grptp == egrptpALL)
2697         {
2698             gmx_fatal(FARGS, "%d atoms are not part of any of the %s groups",
2699                       natoms-ntot, title);
2700         }
2701         else if (grptp == egrptpPART)
2702         {
2703             sprintf(warn_buf, "%d atoms are not part of any of the %s groups",
2704                     natoms-ntot, title);
2705             warning_note(wi, warn_buf);
2706         }
2707         /* Assign all atoms currently unassigned to a rest group */
2708         for (j = 0; (j < natoms); j++)
2709         {
2710             if (cbuf[j] == NOGID)
2711             {
2712                 cbuf[j] = grps->nr;
2713                 bRest   = TRUE;
2714             }
2715         }
2716         if (grptp != egrptpPART)
2717         {
2718             if (bVerbose)
2719             {
2720                 fprintf(stderr,
2721                         "Making dummy/rest group for %s containing %d elements\n",
2722                         title, natoms-ntot);
2723             }
2724             /* Add group name "rest" */
2725             grps->nm_ind[grps->nr] = restnm;
2726
2727             /* Assign the rest name to all atoms not currently assigned to a group */
2728             for (j = 0; (j < natoms); j++)
2729             {
2730                 if (cbuf[j] == NOGID)
2731                 {
2732                     cbuf[j] = grps->nr;
2733                 }
2734             }
2735             grps->nr++;
2736         }
2737     }
2738
2739     if (grps->nr == 1 && (ntot == 0 || ntot == natoms))
2740     {
2741         /* All atoms are part of one (or no) group, no index required */
2742         groups->ngrpnr[gtype] = 0;
2743         groups->grpnr[gtype]  = nullptr;
2744     }
2745     else
2746     {
2747         groups->ngrpnr[gtype] = natoms;
2748         snew(groups->grpnr[gtype], natoms);
2749         for (j = 0; (j < natoms); j++)
2750         {
2751             groups->grpnr[gtype][j] = cbuf[j];
2752         }
2753     }
2754
2755     sfree(cbuf);
2756
2757     return (bRest && grptp == egrptpPART);
2758 }
2759
2760 static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
2761 {
2762     t_grpopts              *opts;
2763     const gmx_groups_t     *groups;
2764     pull_params_t          *pull;
2765     int                     natoms, ai, aj, i, j, d, g, imin, jmin;
2766     int                    *nrdf2, *na_vcm, na_tot;
2767     double                 *nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub;
2768     ivec                   *dof_vcm;
2769     gmx_mtop_atomloop_all_t aloop;
2770     int                     mol, ftype, as;
2771
2772     /* Calculate nrdf.
2773      * First calc 3xnr-atoms for each group
2774      * then subtract half a degree of freedom for each constraint
2775      *
2776      * Only atoms and nuclei contribute to the degrees of freedom...
2777      */
2778
2779     opts = &ir->opts;
2780
2781     groups = &mtop->groups;
2782     natoms = mtop->natoms;
2783
2784     /* Allocate one more for a possible rest group */
2785     /* We need to sum degrees of freedom into doubles,
2786      * since floats give too low nrdf's above 3 million atoms.
2787      */
2788     snew(nrdf_tc, groups->grps[egcTC].nr+1);
2789     snew(nrdf_vcm, groups->grps[egcVCM].nr+1);
2790     snew(dof_vcm, groups->grps[egcVCM].nr+1);
2791     snew(na_vcm, groups->grps[egcVCM].nr+1);
2792     snew(nrdf_vcm_sub, groups->grps[egcVCM].nr+1);
2793
2794     for (i = 0; i < groups->grps[egcTC].nr; i++)
2795     {
2796         nrdf_tc[i] = 0;
2797     }
2798     for (i = 0; i < groups->grps[egcVCM].nr+1; i++)
2799     {
2800         nrdf_vcm[i]     = 0;
2801         clear_ivec(dof_vcm[i]);
2802         na_vcm[i]       = 0;
2803         nrdf_vcm_sub[i] = 0;
2804     }
2805
2806     snew(nrdf2, natoms);
2807     aloop = gmx_mtop_atomloop_all_init(mtop);
2808     const t_atom *atom;
2809     while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
2810     {
2811         nrdf2[i] = 0;
2812         if (atom->ptype == eptAtom || atom->ptype == eptNucleus)
2813         {
2814             g = getGroupType(groups, egcFREEZE, i);
2815             for (d = 0; d < DIM; d++)
2816             {
2817                 if (opts->nFreeze[g][d] == 0)
2818                 {
2819                     /* Add one DOF for particle i (counted as 2*1) */
2820                     nrdf2[i]                              += 2;
2821                     /* VCM group i has dim d as a DOF */
2822                     dof_vcm[getGroupType(groups, egcVCM, i)][d]  = 1;
2823                 }
2824             }
2825             nrdf_tc [getGroupType(groups, egcTC, i)]  += 0.5*nrdf2[i];
2826             nrdf_vcm[getGroupType(groups, egcVCM, i)] += 0.5*nrdf2[i];
2827         }
2828     }
2829
2830     as = 0;
2831     for (const gmx_molblock_t &molb : mtop->molblock)
2832     {
2833         const gmx_moltype_t &molt = mtop->moltype[molb.type];
2834         atom = molt.atoms.atom;
2835         for (mol = 0; mol < molb.nmol; mol++)
2836         {
2837             for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
2838             {
2839                 gmx::ArrayRef<const int> ia = molt.ilist[ftype].iatoms;
2840                 for (i = 0; i < molt.ilist[ftype].size(); )
2841                 {
2842                     /* Subtract degrees of freedom for the constraints,
2843                      * if the particles still have degrees of freedom left.
2844                      * If one of the particles is a vsite or a shell, then all
2845                      * constraint motion will go there, but since they do not
2846                      * contribute to the constraints the degrees of freedom do not
2847                      * change.
2848                      */
2849                     ai = as + ia[i + 1];
2850                     aj = as + ia[i + 2];
2851                     if (((atom[ia[i + 1]].ptype == eptNucleus) ||
2852                          (atom[ia[i + 1]].ptype == eptAtom)) &&
2853                         ((atom[ia[i + 2]].ptype == eptNucleus) ||
2854                          (atom[ia[i + 2]].ptype == eptAtom)))
2855                     {
2856                         if (nrdf2[ai] > 0)
2857                         {
2858                             jmin = 1;
2859                         }
2860                         else
2861                         {
2862                             jmin = 2;
2863                         }
2864                         if (nrdf2[aj] > 0)
2865                         {
2866                             imin = 1;
2867                         }
2868                         else
2869                         {
2870                             imin = 2;
2871                         }
2872                         imin       = std::min(imin, nrdf2[ai]);
2873                         jmin       = std::min(jmin, nrdf2[aj]);
2874                         nrdf2[ai] -= imin;
2875                         nrdf2[aj] -= jmin;
2876                         nrdf_tc [getGroupType(groups, egcTC, ai)]  -= 0.5*imin;
2877                         nrdf_tc [getGroupType(groups, egcTC, aj)]  -= 0.5*jmin;
2878                         nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
2879                         nrdf_vcm[getGroupType(groups, egcVCM, aj)] -= 0.5*jmin;
2880                     }
2881                     i  += interaction_function[ftype].nratoms+1;
2882                 }
2883             }
2884             gmx::ArrayRef<const int> ia = molt.ilist[F_SETTLE].iatoms;
2885             for (i = 0; i < molt.ilist[F_SETTLE].size(); )
2886             {
2887                 /* Subtract 1 dof from every atom in the SETTLE */
2888                 for (j = 0; j < 3; j++)
2889                 {
2890                     ai         = as + ia[i + 1 + j];
2891                     imin       = std::min(2, nrdf2[ai]);
2892                     nrdf2[ai] -= imin;
2893                     nrdf_tc [getGroupType(groups, egcTC, ai)]  -= 0.5*imin;
2894                     nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
2895                 }
2896                 i  += 4;
2897             }
2898             as += molt.atoms.nr;
2899         }
2900     }
2901
2902     if (ir->bPull)
2903     {
2904         /* Correct nrdf for the COM constraints.
2905          * We correct using the TC and VCM group of the first atom
2906          * in the reference and pull group. If atoms in one pull group
2907          * belong to different TC or VCM groups it is anyhow difficult
2908          * to determine the optimal nrdf assignment.
2909          */
2910         pull = ir->pull;
2911
2912         for (i = 0; i < pull->ncoord; i++)
2913         {
2914             if (pull->coord[i].eType != epullCONSTRAINT)
2915             {
2916                 continue;
2917             }
2918
2919             imin = 1;
2920
2921             for (j = 0; j < 2; j++)
2922             {
2923                 const t_pull_group *pgrp;
2924
2925                 pgrp = &pull->group[pull->coord[i].group[j]];
2926
2927                 if (pgrp->nat > 0)
2928                 {
2929                     /* Subtract 1/2 dof from each group */
2930                     ai = pgrp->ind[0];
2931                     nrdf_tc [getGroupType(groups, egcTC, ai)]  -= 0.5*imin;
2932                     nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
2933                     if (nrdf_tc[getGroupType(groups, egcTC, ai)] < 0)
2934                     {
2935                         gmx_fatal(FARGS, "Center of mass pulling constraints caused the number of degrees of freedom for temperature coupling group %s to be negative", gnames[groups->grps[egcTC].nm_ind[getGroupType(groups, egcTC, ai)]]);
2936                     }
2937                 }
2938                 else
2939                 {
2940                     /* We need to subtract the whole DOF from group j=1 */
2941                     imin += 1;
2942                 }
2943             }
2944         }
2945     }
2946
2947     if (ir->nstcomm != 0)
2948     {
2949         int ndim_rm_vcm;
2950
2951         /* We remove COM motion up to dim ndof_com() */
2952         ndim_rm_vcm = ndof_com(ir);
2953
2954         /* Subtract ndim_rm_vcm (or less with frozen dimensions) from
2955          * the number of degrees of freedom in each vcm group when COM
2956          * translation is removed and 6 when rotation is removed as well.
2957          */
2958         for (j = 0; j < groups->grps[egcVCM].nr+1; j++)
2959         {
2960             switch (ir->comm_mode)
2961             {
2962                 case ecmLINEAR:
2963                 case ecmLINEAR_ACCELERATION_CORRECTION:
2964                     nrdf_vcm_sub[j] = 0;
2965                     for (d = 0; d < ndim_rm_vcm; d++)
2966                     {
2967                         if (dof_vcm[j][d])
2968                         {
2969                             nrdf_vcm_sub[j]++;
2970                         }
2971                     }
2972                     break;
2973                 case ecmANGULAR:
2974                     nrdf_vcm_sub[j] = 6;
2975                     break;
2976                 default:
2977                     gmx_incons("Checking comm_mode");
2978             }
2979         }
2980
2981         for (i = 0; i < groups->grps[egcTC].nr; i++)
2982         {
2983             /* Count the number of atoms of TC group i for every VCM group */
2984             for (j = 0; j < groups->grps[egcVCM].nr+1; j++)
2985             {
2986                 na_vcm[j] = 0;
2987             }
2988             na_tot = 0;
2989             for (ai = 0; ai < natoms; ai++)
2990             {
2991                 if (getGroupType(groups, egcTC, ai) == i)
2992                 {
2993                     na_vcm[getGroupType(groups, egcVCM, ai)]++;
2994                     na_tot++;
2995                 }
2996             }
2997             /* Correct for VCM removal according to the fraction of each VCM
2998              * group present in this TC group.
2999              */
3000             nrdf_uc    = nrdf_tc[i];
3001             nrdf_tc[i] = 0;
3002             for (j = 0; j < groups->grps[egcVCM].nr+1; j++)
3003             {
3004                 if (nrdf_vcm[j] > nrdf_vcm_sub[j])
3005                 {
3006                     nrdf_tc[i] += nrdf_uc*(static_cast<double>(na_vcm[j])/static_cast<double>(na_tot))*
3007                         (nrdf_vcm[j] - nrdf_vcm_sub[j])/nrdf_vcm[j];
3008                 }
3009             }
3010         }
3011     }
3012     for (i = 0; (i < groups->grps[egcTC].nr); i++)
3013     {
3014         opts->nrdf[i] = nrdf_tc[i];
3015         if (opts->nrdf[i] < 0)
3016         {
3017             opts->nrdf[i] = 0;
3018         }
3019         fprintf(stderr,
3020                 "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
3021                 gnames[groups->grps[egcTC].nm_ind[i]], opts->nrdf[i]);
3022     }
3023
3024     sfree(nrdf2);
3025     sfree(nrdf_tc);
3026     sfree(nrdf_vcm);
3027     sfree(dof_vcm);
3028     sfree(na_vcm);
3029     sfree(nrdf_vcm_sub);
3030 }
3031
3032 static bool do_egp_flag(t_inputrec *ir, gmx_groups_t *groups,
3033                         const char *option, const char *val, int flag)
3034 {
3035     /* The maximum number of energy group pairs would be MAXPTR*(MAXPTR+1)/2.
3036      * But since this is much larger than STRLEN, such a line can not be parsed.
3037      * The real maximum is the number of names that fit in a string: STRLEN/2.
3038      */
3039 #define EGP_MAX (STRLEN/2)
3040     int      j, k, nr;
3041     char  ***gnames;
3042     bool     bSet;
3043
3044     gnames = groups->grpname;
3045
3046     auto names = gmx::splitString(val);
3047     if (names.size() % 2 != 0)
3048     {
3049         gmx_fatal(FARGS, "The number of groups for %s is odd", option);
3050     }
3051     nr   = groups->grps[egcENER].nr;
3052     bSet = FALSE;
3053     for (size_t i = 0; i < names.size() / 2; i++)
3054     {
3055         j = 0;
3056         while ((j < nr) &&
3057                gmx_strcasecmp(names[2*i].c_str(), *(gnames[groups->grps[egcENER].nm_ind[j]])))
3058         {
3059             j++;
3060         }
3061         if (j == nr)
3062         {
3063             gmx_fatal(FARGS, "%s in %s is not an energy group\n",
3064                       names[2*i].c_str(), option);
3065         }
3066         k = 0;
3067         while ((k < nr) &&
3068                gmx_strcasecmp(names[2*i+1].c_str(), *(gnames[groups->grps[egcENER].nm_ind[k]])))
3069         {
3070             k++;
3071         }
3072         if (k == nr)
3073         {
3074             gmx_fatal(FARGS, "%s in %s is not an energy group\n",
3075                       names[2*i+1].c_str(), option);
3076         }
3077         if ((j < nr) && (k < nr))
3078         {
3079             ir->opts.egp_flags[nr*j+k] |= flag;
3080             ir->opts.egp_flags[nr*k+j] |= flag;
3081             bSet = TRUE;
3082         }
3083     }
3084
3085     return bSet;
3086 }
3087
3088
3089 static void make_swap_groups(
3090         t_swapcoords  *swap,
3091         t_blocka      *grps,
3092         char         **gnames)
3093 {
3094     int          ig = -1, i = 0, gind;
3095     t_swapGroup *swapg;
3096
3097
3098     /* Just a quick check here, more thorough checks are in mdrun */
3099     if (strcmp(swap->grp[eGrpSplit0].molname, swap->grp[eGrpSplit1].molname) == 0)
3100     {
3101         gmx_fatal(FARGS, "The split groups can not both be '%s'.", swap->grp[eGrpSplit0].molname);
3102     }
3103
3104     /* Get the index atoms of the split0, split1, solvent, and swap groups */
3105     for (ig = 0; ig < swap->ngrp; ig++)
3106     {
3107         swapg      = &swap->grp[ig];
3108         gind       = search_string(swap->grp[ig].molname, grps->nr, gnames);
3109         swapg->nat = grps->index[gind+1] - grps->index[gind];
3110
3111         if (swapg->nat > 0)
3112         {
3113             fprintf(stderr, "%s group '%s' contains %d atoms.\n",
3114                     ig < 3 ? eSwapFixedGrp_names[ig] : "Swap",
3115                     swap->grp[ig].molname, swapg->nat);
3116             snew(swapg->ind, swapg->nat);
3117             for (i = 0; i < swapg->nat; i++)
3118             {
3119                 swapg->ind[i] = grps->a[grps->index[gind]+i];
3120             }
3121         }
3122         else
3123         {
3124             gmx_fatal(FARGS, "Swap group %s does not contain any atoms.", swap->grp[ig].molname);
3125         }
3126     }
3127 }
3128
3129
3130 static void make_IMD_group(t_IMD *IMDgroup, char *IMDgname, t_blocka *grps, char **gnames)
3131 {
3132     int      ig, i;
3133
3134
3135     ig            = search_string(IMDgname, grps->nr, gnames);
3136     IMDgroup->nat = grps->index[ig+1] - grps->index[ig];
3137
3138     if (IMDgroup->nat > 0)
3139     {
3140         fprintf(stderr, "Group '%s' with %d atoms can be activated for interactive molecular dynamics (IMD).\n",
3141                 IMDgname, IMDgroup->nat);
3142         snew(IMDgroup->ind, IMDgroup->nat);
3143         for (i = 0; i < IMDgroup->nat; i++)
3144         {
3145             IMDgroup->ind[i] = grps->a[grps->index[ig]+i];
3146         }
3147     }
3148 }
3149
3150 void do_index(const char* mdparin, const char *ndx,
3151               gmx_mtop_t *mtop,
3152               bool bVerbose,
3153               t_inputrec *ir,
3154               warninp_t wi)
3155 {
3156     t_blocka     *grps;
3157     gmx_groups_t *groups;
3158     int           natoms;
3159     t_symtab     *symtab;
3160     t_atoms       atoms_all;
3161     char          warnbuf[STRLEN], **gnames;
3162     int           nr;
3163     real          tau_min;
3164     int           nstcmin;
3165     int           i, j, k, restnm;
3166     bool          bExcl, bTable, bAnneal, bRest;
3167     char          warn_buf[STRLEN];
3168
3169     if (bVerbose)
3170     {
3171         fprintf(stderr, "processing index file...\n");
3172     }
3173     if (ndx == nullptr)
3174     {
3175         snew(grps, 1);
3176         snew(grps->index, 1);
3177         snew(gnames, 1);
3178         atoms_all = gmx_mtop_global_atoms(mtop);
3179         analyse(&atoms_all, grps, &gnames, FALSE, TRUE);
3180         done_atom(&atoms_all);
3181     }
3182     else
3183     {
3184         grps = init_index(ndx, &gnames);
3185     }
3186
3187     groups = &mtop->groups;
3188     natoms = mtop->natoms;
3189     symtab = &mtop->symtab;
3190
3191     snew(groups->grpname, grps->nr+1);
3192
3193     for (i = 0; (i < grps->nr); i++)
3194     {
3195         groups->grpname[i] = put_symtab(symtab, gnames[i]);
3196     }
3197     groups->grpname[i] = put_symtab(symtab, "rest");
3198     restnm             = i;
3199     srenew(gnames, grps->nr+1);
3200     gnames[restnm]   = *(groups->grpname[i]);
3201     groups->ngrpname = grps->nr+1;
3202
3203     set_warning_line(wi, mdparin, -1);
3204
3205     auto temperatureCouplingTauValues       = gmx::splitString(is->tau_t);
3206     auto temperatureCouplingReferenceValues = gmx::splitString(is->ref_t);
3207     auto temperatureCouplingGroupNames      = gmx::splitString(is->tcgrps);
3208     if (temperatureCouplingTauValues.size() != temperatureCouplingGroupNames.size() ||
3209         temperatureCouplingReferenceValues.size() != temperatureCouplingGroupNames.size())
3210     {
3211         gmx_fatal(FARGS, "Invalid T coupling input: %zu groups, %zu ref-t values and "
3212                   "%zu tau-t values",
3213                   temperatureCouplingGroupNames.size(),
3214                   temperatureCouplingReferenceValues.size(),
3215                   temperatureCouplingTauValues.size());
3216     }
3217
3218     const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
3219     do_numbering(natoms, groups, temperatureCouplingGroupNames, grps, gnames, egcTC,
3220                  restnm, useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
3221     nr            = groups->grps[egcTC].nr;
3222     ir->opts.ngtc = nr;
3223     snew(ir->opts.nrdf, nr);
3224     snew(ir->opts.tau_t, nr);
3225     snew(ir->opts.ref_t, nr);
3226     if (ir->eI == eiBD && ir->bd_fric == 0)
3227     {
3228         fprintf(stderr, "bd-fric=0, so tau-t will be used as the inverse friction constant(s)\n");
3229     }
3230
3231     if (useReferenceTemperature)
3232     {
3233         if (size_t(nr) != temperatureCouplingReferenceValues.size())
3234         {
3235             gmx_fatal(FARGS, "Not enough ref-t and tau-t values!");
3236         }
3237
3238         tau_min = 1e20;
3239         convertReals(wi, temperatureCouplingTauValues, "tau-t", ir->opts.tau_t);
3240         for (i = 0; (i < nr); i++)
3241         {
3242             if ((ir->eI == eiBD) && ir->opts.tau_t[i] <= 0)
3243             {
3244                 sprintf(warn_buf, "With integrator %s tau-t should be larger than 0", ei_names[ir->eI]);
3245                 warning_error(wi, warn_buf);
3246             }
3247
3248             if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
3249             {
3250                 warning_note(wi, "tau-t = -1 is the value to signal that a group should not have temperature coupling. Treating your use of tau-t = 0 as if you used -1.");
3251             }
3252
3253             if (ir->opts.tau_t[i] >= 0)
3254             {
3255                 tau_min = std::min(tau_min, ir->opts.tau_t[i]);
3256             }
3257         }
3258         if (ir->etc != etcNO && ir->nsttcouple == -1)
3259         {
3260             ir->nsttcouple = ir_optimal_nsttcouple(ir);
3261         }
3262
3263         if (EI_VV(ir->eI))
3264         {
3265             if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
3266             {
3267                 gmx_fatal(FARGS, "Cannot do Nose-Hoover temperature with Berendsen pressure control with md-vv; use either vrescale temperature with berendsen pressure or Nose-Hoover temperature with MTTK pressure");
3268             }
3269             if (ir->epc == epcMTTK)
3270             {
3271                 if (ir->etc != etcNOSEHOOVER)
3272                 {
3273                     gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
3274                 }
3275                 else
3276                 {
3277                     if (ir->nstpcouple != ir->nsttcouple)
3278                     {
3279                         int mincouple = std::min(ir->nstpcouple, ir->nsttcouple);
3280                         ir->nstpcouple = ir->nsttcouple = mincouple;
3281                         sprintf(warn_buf, "for current Trotter decomposition methods with vv, nsttcouple and nstpcouple must be equal.  Both have been reset to min(nsttcouple,nstpcouple) = %d", mincouple);
3282                         warning_note(wi, warn_buf);
3283                     }
3284                 }
3285             }
3286         }
3287         /* velocity verlet with averaged kinetic energy KE = 0.5*(v(t+1/2) - v(t-1/2)) is implemented
3288            primarily for testing purposes, and does not work with temperature coupling other than 1 */
3289
3290         if (ETC_ANDERSEN(ir->etc))
3291         {
3292             if (ir->nsttcouple != 1)
3293             {
3294                 ir->nsttcouple = 1;
3295                 sprintf(warn_buf, "Andersen temperature control methods assume nsttcouple = 1; there is no need for larger nsttcouple > 1, since no global parameters are computed. nsttcouple has been reset to 1");
3296                 warning_note(wi, warn_buf);
3297             }
3298         }
3299         nstcmin = tcouple_min_integration_steps(ir->etc);
3300         if (nstcmin > 1)
3301         {
3302             if (tau_min/(ir->delta_t*ir->nsttcouple) < nstcmin - 10*GMX_REAL_EPS)
3303             {
3304                 sprintf(warn_buf, "For proper integration of the %s thermostat, tau-t (%g) should be at least %d times larger than nsttcouple*dt (%g)",
3305                         ETCOUPLTYPE(ir->etc),
3306                         tau_min, nstcmin,
3307                         ir->nsttcouple*ir->delta_t);
3308                 warning(wi, warn_buf);
3309             }
3310         }
3311         convertReals(wi, temperatureCouplingReferenceValues, "ref-t", ir->opts.ref_t);
3312         for (i = 0; (i < nr); i++)
3313         {
3314             if (ir->opts.ref_t[i] < 0)
3315             {
3316                 gmx_fatal(FARGS, "ref-t for group %d negative", i);
3317             }
3318         }
3319         /* set the lambda mc temperature to the md integrator temperature (which should be defined
3320            if we are in this conditional) if mc_temp is negative */
3321         if (ir->expandedvals->mc_temp < 0)
3322         {
3323             ir->expandedvals->mc_temp = ir->opts.ref_t[0]; /*for now, set to the first reft */
3324         }
3325     }
3326
3327     /* Simulated annealing for each group. There are nr groups */
3328     auto simulatedAnnealingGroupNames = gmx::splitString(is->anneal);
3329     if (simulatedAnnealingGroupNames.size() == 1 &&
3330         gmx_strncasecmp(simulatedAnnealingGroupNames[0].c_str(), "N", 1) == 0)
3331     {
3332         simulatedAnnealingGroupNames.resize(0);
3333     }
3334     if (!simulatedAnnealingGroupNames.empty() &&
3335         simulatedAnnealingGroupNames.size() != size_t(nr))
3336     {
3337         gmx_fatal(FARGS, "Not enough annealing values: %zu (for %d groups)\n",
3338                   simulatedAnnealingGroupNames.size(), nr);
3339     }
3340     else
3341     {
3342         snew(ir->opts.annealing, nr);
3343         snew(ir->opts.anneal_npoints, nr);
3344         snew(ir->opts.anneal_time, nr);
3345         snew(ir->opts.anneal_temp, nr);
3346         for (i = 0; i < nr; i++)
3347         {
3348             ir->opts.annealing[i]      = eannNO;
3349             ir->opts.anneal_npoints[i] = 0;
3350             ir->opts.anneal_time[i]    = nullptr;
3351             ir->opts.anneal_temp[i]    = nullptr;
3352         }
3353         if (!simulatedAnnealingGroupNames.empty())
3354         {
3355             bAnneal = FALSE;
3356             for (i = 0; i < nr; i++)
3357             {
3358                 if (gmx_strncasecmp(simulatedAnnealingGroupNames[i].c_str(), "N", 1) == 0)
3359                 {
3360                     ir->opts.annealing[i] = eannNO;
3361                 }
3362                 else if (gmx_strncasecmp(simulatedAnnealingGroupNames[i].c_str(), "S", 1) == 0)
3363                 {
3364                     ir->opts.annealing[i] = eannSINGLE;
3365                     bAnneal               = TRUE;
3366                 }
3367                 else if (gmx_strncasecmp(simulatedAnnealingGroupNames[i].c_str(), "P", 1) == 0)
3368                 {
3369                     ir->opts.annealing[i] = eannPERIODIC;
3370                     bAnneal               = TRUE;
3371                 }
3372             }
3373             if (bAnneal)
3374             {
3375                 /* Read the other fields too */
3376                 auto simulatedAnnealingPoints = gmx::splitString(is->anneal_npoints);
3377                 if (simulatedAnnealingPoints.size() != simulatedAnnealingGroupNames.size())
3378                 {
3379                     gmx_fatal(FARGS, "Found %zu annealing-npoints values for %zu groups\n",
3380                               simulatedAnnealingPoints.size(), simulatedAnnealingGroupNames.size());
3381                 }
3382                 convertInts(wi, simulatedAnnealingPoints, "annealing points", ir->opts.anneal_npoints);
3383                 for (k = 0, i = 0; i < nr; i++)
3384                 {
3385                     if (ir->opts.anneal_npoints[i] == 1)
3386                     {
3387                         gmx_fatal(FARGS, "Please specify at least a start and an end point for annealing\n");
3388                     }
3389                     snew(ir->opts.anneal_time[i], ir->opts.anneal_npoints[i]);
3390                     snew(ir->opts.anneal_temp[i], ir->opts.anneal_npoints[i]);
3391                     k += ir->opts.anneal_npoints[i];
3392                 }
3393
3394                 auto simulatedAnnealingTimes = gmx::splitString(is->anneal_time);
3395                 if (simulatedAnnealingTimes.size() != size_t(k))
3396                 {
3397                     gmx_fatal(FARGS, "Found %zu annealing-time values, wanted %d\n",
3398                               simulatedAnnealingTimes.size(), k);
3399                 }
3400                 auto simulatedAnnealingTemperatures = gmx::splitString(is->anneal_temp);
3401                 if (simulatedAnnealingTemperatures.size() != size_t(k))
3402                 {
3403                     gmx_fatal(FARGS, "Found %zu annealing-temp values, wanted %d\n",
3404                               simulatedAnnealingTemperatures.size(), k);
3405                 }
3406
3407                 convertReals(wi, simulatedAnnealingTimes, "anneal-time", ir->opts.anneal_time[i]);
3408                 convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp", ir->opts.anneal_temp[i]);
3409                 for (i = 0, k = 0; i < nr; i++)
3410                 {
3411                     for (j = 0; j < ir->opts.anneal_npoints[i]; j++)
3412                     {
3413                         if (j == 0)
3414                         {
3415                             if (ir->opts.anneal_time[i][0] > (ir->init_t+GMX_REAL_EPS))
3416                             {
3417                                 gmx_fatal(FARGS, "First time point for annealing > init_t.\n");
3418                             }
3419                         }
3420                         else
3421                         {
3422                             /* j>0 */
3423                             if (ir->opts.anneal_time[i][j] < ir->opts.anneal_time[i][j-1])
3424                             {
3425                                 gmx_fatal(FARGS, "Annealing timepoints out of order: t=%f comes after t=%f\n",
3426                                           ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j-1]);
3427                             }
3428                         }
3429                         if (ir->opts.anneal_temp[i][j] < 0)
3430                         {
3431                             gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n", ir->opts.anneal_temp[i][j]);
3432                         }
3433                         k++;
3434                     }
3435                 }
3436                 /* Print out some summary information, to make sure we got it right */
3437                 for (i = 0, k = 0; i < nr; i++)
3438                 {
3439                     if (ir->opts.annealing[i] != eannNO)
3440                     {
3441                         j = groups->grps[egcTC].nm_ind[i];
3442                         fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
3443                                 *(groups->grpname[j]), eann_names[ir->opts.annealing[i]],
3444                                 ir->opts.anneal_npoints[i]);
3445                         fprintf(stderr, "Time (ps)   Temperature (K)\n");
3446                         /* All terms except the last one */
3447                         for (j = 0; j < (ir->opts.anneal_npoints[i]-1); j++)
3448                         {
3449                             fprintf(stderr, "%9.1f      %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3450                         }
3451
3452                         /* Finally the last one */
3453                         j = ir->opts.anneal_npoints[i]-1;
3454                         if (ir->opts.annealing[i] == eannSINGLE)
3455                         {
3456                             fprintf(stderr, "%9.1f-     %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3457                         }
3458                         else
3459                         {
3460                             fprintf(stderr, "%9.1f      %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3461                             if (std::fabs(ir->opts.anneal_temp[i][j]-ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS)
3462                             {
3463                                 warning_note(wi, "There is a temperature jump when your annealing loops back.\n");
3464                             }
3465                         }
3466                     }
3467                 }
3468             }
3469         }
3470     }
3471
3472     if (ir->bPull)
3473     {
3474         make_pull_groups(ir->pull, is->pull_grp, grps, gnames);
3475
3476         make_pull_coords(ir->pull);
3477     }
3478
3479     if (ir->bRot)
3480     {
3481         make_rotation_groups(ir->rot, is->rot_grp, grps, gnames);
3482     }
3483
3484     if (ir->eSwapCoords != eswapNO)
3485     {
3486         make_swap_groups(ir->swap, grps, gnames);
3487     }
3488
3489     /* Make indices for IMD session */
3490     if (ir->bIMD)
3491     {
3492         make_IMD_group(ir->imd, is->imd_grp, grps, gnames);
3493     }
3494
3495     auto accelerations          = gmx::splitString(is->acc);
3496     auto accelerationGroupNames = gmx::splitString(is->accgrps);
3497     if (accelerationGroupNames.size() * DIM != accelerations.size())
3498     {
3499         gmx_fatal(FARGS, "Invalid Acceleration input: %zu groups and %zu acc. values",
3500                   accelerationGroupNames.size(), accelerations.size());
3501     }
3502     do_numbering(natoms, groups, accelerationGroupNames, grps, gnames, egcACC,
3503                  restnm, egrptpALL_GENREST, bVerbose, wi);
3504     nr = groups->grps[egcACC].nr;
3505     snew(ir->opts.acc, nr);
3506     ir->opts.ngacc = nr;
3507
3508     convertRvecs(wi, accelerations, "anneal-time", ir->opts.acc);
3509
3510     auto freezeDims       = gmx::splitString(is->frdim);
3511     auto freezeGroupNames = gmx::splitString(is->freeze);
3512     if (freezeDims.size() != DIM * freezeGroupNames.size())
3513     {
3514         gmx_fatal(FARGS, "Invalid Freezing input: %zu groups and %zu freeze values",
3515                   freezeGroupNames.size(), freezeDims.size());
3516     }
3517     do_numbering(natoms, groups, freezeGroupNames, grps, gnames, egcFREEZE,
3518                  restnm, egrptpALL_GENREST, bVerbose, wi);
3519     nr             = groups->grps[egcFREEZE].nr;
3520     ir->opts.ngfrz = nr;
3521     snew(ir->opts.nFreeze, nr);
3522     for (i = k = 0; (size_t(i) < freezeGroupNames.size()); i++)
3523     {
3524         for (j = 0; (j < DIM); j++, k++)
3525         {
3526             ir->opts.nFreeze[i][j] = static_cast<int>(gmx_strncasecmp(freezeDims[k].c_str(), "Y", 1) == 0);
3527             if (!ir->opts.nFreeze[i][j])
3528             {
3529                 if (gmx_strncasecmp(freezeDims[k].c_str(), "N", 1) != 0)
3530                 {
3531                     sprintf(warnbuf, "Please use Y(ES) or N(O) for freezedim only "
3532                             "(not %s)", freezeDims[k].c_str());
3533                     warning(wi, warn_buf);
3534                 }
3535             }
3536         }
3537     }
3538     for (; (i < nr); i++)
3539     {
3540         for (j = 0; (j < DIM); j++)
3541         {
3542             ir->opts.nFreeze[i][j] = 0;
3543         }
3544     }
3545
3546     auto energyGroupNames = gmx::splitString(is->energy);
3547     do_numbering(natoms, groups, energyGroupNames, grps, gnames, egcENER,
3548                  restnm, egrptpALL_GENREST, bVerbose, wi);
3549     add_wall_energrps(groups, ir->nwall, symtab);
3550     ir->opts.ngener = groups->grps[egcENER].nr;
3551     auto vcmGroupNames = gmx::splitString(is->vcm);
3552     bRest           =
3553         do_numbering(natoms, groups, vcmGroupNames, grps, gnames, egcVCM,
3554                      restnm, vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
3555     if (bRest)
3556     {
3557         warning(wi, "Some atoms are not part of any center of mass motion removal group.\n"
3558                 "This may lead to artifacts.\n"
3559                 "In most cases one should use one group for the whole system.");
3560     }
3561
3562     /* Now we have filled the freeze struct, so we can calculate NRDF */
3563     calc_nrdf(mtop, ir, gnames);
3564
3565     auto user1GroupNames = gmx::splitString(is->user1);
3566     do_numbering(natoms, groups, user1GroupNames, grps, gnames, egcUser1,
3567                  restnm, egrptpALL_GENREST, bVerbose, wi);
3568     auto user2GroupNames = gmx::splitString(is->user2);
3569     do_numbering(natoms, groups, user2GroupNames, grps, gnames, egcUser2,
3570                  restnm, egrptpALL_GENREST, bVerbose, wi);
3571     auto compressedXGroupNames = gmx::splitString(is->x_compressed_groups);
3572     do_numbering(natoms, groups, compressedXGroupNames, grps, gnames, egcCompressedX,
3573                  restnm, egrptpONE, bVerbose, wi);
3574     auto orirefFitGroupNames = gmx::splitString(is->orirefitgrp);
3575     do_numbering(natoms, groups, orirefFitGroupNames, grps, gnames, egcORFIT,
3576                  restnm, egrptpALL_GENREST, bVerbose, wi);
3577
3578     /* QMMM input processing */
3579     auto qmGroupNames = gmx::splitString(is->QMMM);
3580     auto qmMethods    = gmx::splitString(is->QMmethod);
3581     auto qmBasisSets  = gmx::splitString(is->QMbasis);
3582     if (ir->eI != eiMimic)
3583     {
3584         if (qmMethods.size() != qmGroupNames.size() ||
3585             qmBasisSets.size() != qmGroupNames.size())
3586         {
3587             gmx_fatal(FARGS, "Invalid QMMM input: %zu groups %zu basissets"
3588                       " and %zu methods\n", qmGroupNames.size(),
3589                       qmBasisSets.size(), qmMethods.size());
3590         }
3591         /* group rest, if any, is always MM! */
3592         do_numbering(natoms, groups, qmGroupNames, grps, gnames, egcQMMM,
3593                      restnm, egrptpALL_GENREST, bVerbose, wi);
3594         nr            = qmGroupNames.size(); /*atoms->grps[egcQMMM].nr;*/
3595         ir->opts.ngQM = qmGroupNames.size();
3596         snew(ir->opts.QMmethod, nr);
3597         snew(ir->opts.QMbasis, nr);
3598         for (i = 0; i < nr; i++)
3599         {
3600             /* input consists of strings: RHF CASSCF PM3 .. These need to be
3601              * converted to the corresponding enum in names.c
3602              */
3603             ir->opts.QMmethod[i] = search_QMstring(qmMethods[i].c_str(),
3604                                                    eQMmethodNR,
3605                                                    eQMmethod_names);
3606             ir->opts.QMbasis[i] = search_QMstring(qmBasisSets[i].c_str(),
3607                                                   eQMbasisNR,
3608                                                   eQMbasis_names);
3609
3610         }
3611         auto qmMultiplicities = gmx::splitString(is->QMmult);
3612         auto qmCharges        = gmx::splitString(is->QMcharge);
3613         auto qmbSH            = gmx::splitString(is->bSH);
3614         snew(ir->opts.QMmult, nr);
3615         snew(ir->opts.QMcharge, nr);
3616         snew(ir->opts.bSH, nr);
3617         convertInts(wi, qmMultiplicities, "QMmult", ir->opts.QMmult);
3618         convertInts(wi, qmCharges, "QMcharge", ir->opts.QMcharge);
3619         convertYesNos(wi, qmbSH, "bSH", ir->opts.bSH);
3620
3621         auto CASelectrons = gmx::splitString(is->CASelectrons);
3622         auto CASorbitals  = gmx::splitString(is->CASorbitals);
3623         snew(ir->opts.CASelectrons, nr);
3624         snew(ir->opts.CASorbitals, nr);
3625         convertInts(wi, CASelectrons, "CASelectrons", ir->opts.CASelectrons);
3626         convertInts(wi, CASorbitals, "CASOrbitals", ir->opts.CASorbitals);
3627
3628         auto SAon    = gmx::splitString(is->SAon);
3629         auto SAoff   = gmx::splitString(is->SAoff);
3630         auto SAsteps = gmx::splitString(is->SAsteps);
3631         snew(ir->opts.SAon, nr);
3632         snew(ir->opts.SAoff, nr);
3633         snew(ir->opts.SAsteps, nr);
3634         convertInts(wi, SAon, "SAon", ir->opts.SAon);
3635         convertInts(wi, SAoff, "SAoff", ir->opts.SAoff);
3636         convertInts(wi, SAsteps, "SAsteps", ir->opts.SAsteps);
3637     }
3638     else
3639     {
3640         /* MiMiC */
3641         if (qmGroupNames.size() > 1)
3642         {
3643             gmx_fatal(FARGS, "Currently, having more than one QM group in MiMiC is not supported");
3644         }
3645         /* group rest, if any, is always MM! */
3646         do_numbering(natoms, groups, qmGroupNames, grps, gnames, egcQMMM,
3647                      restnm, egrptpALL_GENREST, bVerbose, wi);
3648
3649         ir->opts.ngQM = qmGroupNames.size();
3650     }
3651
3652     /* end of QMMM input */
3653
3654     if (bVerbose)
3655     {
3656         for (i = 0; (i < egcNR); i++)
3657         {
3658             fprintf(stderr, "%-16s has %d element(s):", gtypes[i], groups->grps[i].nr);
3659             for (j = 0; (j < groups->grps[i].nr); j++)
3660             {
3661                 fprintf(stderr, " %s", *(groups->grpname[groups->grps[i].nm_ind[j]]));
3662             }
3663             fprintf(stderr, "\n");
3664         }
3665     }
3666
3667     nr = groups->grps[egcENER].nr;
3668     snew(ir->opts.egp_flags, nr*nr);
3669
3670     bExcl = do_egp_flag(ir, groups, "energygrp-excl", is->egpexcl, EGP_EXCL);
3671     if (bExcl && ir->cutoff_scheme == ecutsVERLET)
3672     {
3673         warning_error(wi, "Energy group exclusions are not (yet) implemented for the Verlet scheme");
3674     }
3675     if (bExcl && EEL_FULL(ir->coulombtype))
3676     {
3677         warning(wi, "Can not exclude the lattice Coulomb energy between energy groups");
3678     }
3679
3680     bTable = do_egp_flag(ir, groups, "energygrp-table", is->egptable, EGP_TABLE);
3681     if (bTable && !(ir->vdwtype == evdwUSER) &&
3682         !(ir->coulombtype == eelUSER) && !(ir->coulombtype == eelPMEUSER) &&
3683         !(ir->coulombtype == eelPMEUSERSWITCH))
3684     {
3685         gmx_fatal(FARGS, "Can only have energy group pair tables in combination with user tables for VdW and/or Coulomb");
3686     }
3687
3688     for (i = 0; (i < grps->nr); i++)
3689     {
3690         sfree(gnames[i]);
3691     }
3692     sfree(gnames);
3693     done_blocka(grps);
3694     sfree(grps);
3695
3696 }
3697
3698
3699
3700 static void check_disre(const gmx_mtop_t *mtop)
3701 {
3702     if (gmx_mtop_ftype_count(mtop, F_DISRES) > 0)
3703     {
3704         const gmx_ffparams_t &ffparams  = mtop->ffparams;
3705         int                   ndouble   = 0;
3706         int                   old_label = -1;
3707         for (int i = 0; i < ffparams.numTypes(); i++)
3708         {
3709             int ftype = ffparams.functype[i];
3710             if (ftype == F_DISRES)
3711             {
3712                 int label = ffparams.iparams[i].disres.label;
3713                 if (label == old_label)
3714                 {
3715                     fprintf(stderr, "Distance restraint index %d occurs twice\n", label);
3716                     ndouble++;
3717                 }
3718                 old_label = label;
3719             }
3720         }
3721         if (ndouble > 0)
3722         {
3723             gmx_fatal(FARGS, "Found %d double distance restraint indices,\n"
3724                       "probably the parameters for multiple pairs in one restraint "
3725                       "are not identical\n", ndouble);
3726         }
3727     }
3728 }
3729
3730 static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys,
3731                                bool posres_only,
3732                                ivec AbsRef)
3733 {
3734     int                    d, g, i;
3735     gmx_mtop_ilistloop_t   iloop;
3736     int                    nmol;
3737     t_iparams             *pr;
3738
3739     clear_ivec(AbsRef);
3740
3741     if (!posres_only)
3742     {
3743         /* Check the COM */
3744         for (d = 0; d < DIM; d++)
3745         {
3746             AbsRef[d] = (d < ndof_com(ir) ? 0 : 1);
3747         }
3748         /* Check for freeze groups */
3749         for (g = 0; g < ir->opts.ngfrz; g++)
3750         {
3751             for (d = 0; d < DIM; d++)
3752             {
3753                 if (ir->opts.nFreeze[g][d] != 0)
3754                 {
3755                     AbsRef[d] = 1;
3756                 }
3757             }
3758         }
3759     }
3760
3761     /* Check for position restraints */
3762     iloop = gmx_mtop_ilistloop_init(sys);
3763     while (const InteractionLists *ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
3764     {
3765         if (nmol > 0 &&
3766             (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
3767         {
3768             for (i = 0; i < (*ilist)[F_POSRES].size(); i += 2)
3769             {
3770                 pr = &sys->ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]];
3771                 for (d = 0; d < DIM; d++)
3772                 {
3773                     if (pr->posres.fcA[d] != 0)
3774                     {
3775                         AbsRef[d] = 1;
3776                     }
3777                 }
3778             }
3779             for (i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2)
3780             {
3781                 /* Check for flat-bottom posres */
3782                 pr = &sys->ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]];
3783                 if (pr->fbposres.k != 0)
3784                 {
3785                     switch (pr->fbposres.geom)
3786                     {
3787                         case efbposresSPHERE:
3788                             AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1;
3789                             break;
3790                         case efbposresCYLINDERX:
3791                             AbsRef[YY] = AbsRef[ZZ] = 1;
3792                             break;
3793                         case efbposresCYLINDERY:
3794                             AbsRef[XX] = AbsRef[ZZ] = 1;
3795                             break;
3796                         case efbposresCYLINDER:
3797                         /* efbposres is a synonym for efbposresCYLINDERZ for backwards compatibility */
3798                         case efbposresCYLINDERZ:
3799                             AbsRef[XX] = AbsRef[YY] = 1;
3800                             break;
3801                         case efbposresX: /* d=XX */
3802                         case efbposresY: /* d=YY */
3803                         case efbposresZ: /* d=ZZ */
3804                             d         = pr->fbposres.geom - efbposresX;
3805                             AbsRef[d] = 1;
3806                             break;
3807                         default:
3808                             gmx_fatal(FARGS, " Invalid geometry for flat-bottom position restraint.\n"
3809                                       "Expected nr between 1 and %d. Found %d\n", efbposresNR-1,
3810                                       pr->fbposres.geom);
3811                     }
3812                 }
3813             }
3814         }
3815     }
3816
3817     return (AbsRef[XX] != 0 && AbsRef[YY] != 0 && AbsRef[ZZ] != 0);
3818 }
3819
3820 static void
3821 check_combination_rule_differences(const gmx_mtop_t *mtop, int state,
3822                                    bool *bC6ParametersWorkWithGeometricRules,
3823                                    bool *bC6ParametersWorkWithLBRules,
3824                                    bool *bLBRulesPossible)
3825 {
3826     int           ntypes, tpi, tpj;
3827     int          *typecount;
3828     real          tol;
3829     double        c6i, c6j, c12i, c12j;
3830     double        c6, c6_geometric, c6_LB;
3831     double        sigmai, sigmaj, epsi, epsj;
3832     bool          bCanDoLBRules, bCanDoGeometricRules;
3833     const char   *ptr;
3834
3835     /* A tolerance of 1e-5 seems reasonable for (possibly hand-typed)
3836      * force-field floating point parameters.
3837      */
3838     tol = 1e-5;
3839     ptr = getenv("GMX_LJCOMB_TOL");
3840     if (ptr != nullptr)
3841     {
3842         double            dbl;
3843         double gmx_unused canary;
3844
3845         if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
3846         {
3847             gmx_fatal(FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
3848         }
3849         tol = dbl;
3850     }
3851
3852     *bC6ParametersWorkWithLBRules         = TRUE;
3853     *bC6ParametersWorkWithGeometricRules  = TRUE;
3854     bCanDoLBRules                         = TRUE;
3855     ntypes                                = mtop->ffparams.atnr;
3856     snew(typecount, ntypes);
3857     gmx_mtop_count_atomtypes(mtop, state, typecount);
3858     *bLBRulesPossible       = TRUE;
3859     for (tpi = 0; tpi < ntypes; ++tpi)
3860     {
3861         c6i  = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c6;
3862         c12i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c12;
3863         for (tpj = tpi; tpj < ntypes; ++tpj)
3864         {
3865             c6j          = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
3866             c12j         = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
3867             c6           = mtop->ffparams.iparams[ntypes * tpi + tpj].lj.c6;
3868             c6_geometric = std::sqrt(c6i * c6j);
3869             if (!gmx_numzero(c6_geometric))
3870             {
3871                 if (!gmx_numzero(c12i) && !gmx_numzero(c12j))
3872                 {
3873                     sigmai   = gmx::sixthroot(c12i / c6i);
3874                     sigmaj   = gmx::sixthroot(c12j / c6j);
3875                     epsi     = c6i * c6i /(4.0 * c12i);
3876                     epsj     = c6j * c6j /(4.0 * c12j);
3877                     c6_LB    = 4.0 * std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj));
3878                 }
3879                 else
3880                 {
3881                     *bLBRulesPossible = FALSE;
3882                     c6_LB             = c6_geometric;
3883                 }
3884                 bCanDoLBRules = gmx_within_tol(c6_LB, c6, tol);
3885             }
3886
3887             if (!bCanDoLBRules)
3888             {
3889                 *bC6ParametersWorkWithLBRules = FALSE;
3890             }
3891
3892             bCanDoGeometricRules = gmx_within_tol(c6_geometric, c6, tol);
3893
3894             if (!bCanDoGeometricRules)
3895             {
3896                 *bC6ParametersWorkWithGeometricRules = FALSE;
3897             }
3898         }
3899     }
3900     sfree(typecount);
3901 }
3902
3903 static void
3904 check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop,
3905                         warninp_t wi)
3906 {
3907     bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
3908
3909     check_combination_rule_differences(mtop, 0,
3910                                        &bC6ParametersWorkWithGeometricRules,
3911                                        &bC6ParametersWorkWithLBRules,
3912                                        &bLBRulesPossible);
3913     if (ir->ljpme_combination_rule == eljpmeLB)
3914     {
3915         if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
3916         {
3917             warning(wi, "You are using arithmetic-geometric combination rules "
3918                     "in LJ-PME, but your non-bonded C6 parameters do not "
3919                     "follow these rules.");
3920         }
3921     }
3922     else
3923     {
3924         if (!bC6ParametersWorkWithGeometricRules)
3925         {
3926             if (ir->eDispCorr != edispcNO)
3927             {
3928                 warning_note(wi, "You are using geometric combination rules in "
3929                              "LJ-PME, but your non-bonded C6 parameters do "
3930                              "not follow these rules. "
3931                              "This will introduce very small errors in the forces and energies in "
3932                              "your simulations. Dispersion correction will correct total energy "
3933                              "and/or pressure for isotropic systems, but not forces or surface tensions.");
3934             }
3935             else
3936             {
3937                 warning_note(wi, "You are using geometric combination rules in "
3938                              "LJ-PME, but your non-bonded C6 parameters do "
3939                              "not follow these rules. "
3940                              "This will introduce very small errors in the forces and energies in "
3941                              "your simulations. If your system is homogeneous, consider using dispersion correction "
3942                              "for the total energy and pressure.");
3943             }
3944         }
3945     }
3946 }
3947
3948 void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
3949                   warninp_t wi)
3950 {
3951     char                      err_buf[STRLEN];
3952     int                       i, m, c, nmol;
3953     bool                      bCharge, bAcc;
3954     real                     *mgrp, mt;
3955     rvec                      acc;
3956     gmx_mtop_atomloop_block_t aloopb;
3957     gmx_mtop_atomloop_all_t   aloop;
3958     ivec                      AbsRef;
3959     char                      warn_buf[STRLEN];
3960
3961     set_warning_line(wi, mdparin, -1);
3962
3963     if (ir->cutoff_scheme == ecutsVERLET &&
3964         ir->verletbuf_tol > 0 &&
3965         ir->nstlist > 1 &&
3966         ((EI_MD(ir->eI) || EI_SD(ir->eI)) &&
3967          (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
3968     {
3969         /* Check if a too small Verlet buffer might potentially
3970          * cause more drift than the thermostat can couple off.
3971          */
3972         /* Temperature error fraction for warning and suggestion */
3973         const real T_error_warn    = 0.002;
3974         const real T_error_suggest = 0.001;
3975         /* For safety: 2 DOF per atom (typical with constraints) */
3976         const real nrdf_at         = 2;
3977         real       T, tau, max_T_error;
3978         int        i;
3979
3980         T   = 0;
3981         tau = 0;
3982         for (i = 0; i < ir->opts.ngtc; i++)
3983         {
3984             T   = std::max(T, ir->opts.ref_t[i]);
3985             tau = std::max(tau, ir->opts.tau_t[i]);
3986         }
3987         if (T > 0)
3988         {
3989             /* This is a worst case estimate of the temperature error,
3990              * assuming perfect buffer estimation and no cancelation
3991              * of errors. The factor 0.5 is because energy distributes
3992              * equally over Ekin and Epot.
3993              */
3994             max_T_error = 0.5*tau*ir->verletbuf_tol/(nrdf_at*BOLTZ*T);
3995             if (max_T_error > T_error_warn)
3996             {
3997                 sprintf(warn_buf, "With a verlet-buffer-tolerance of %g kJ/mol/ps, a reference temperature of %g and a tau_t of %g, your temperature might be off by up to %.1f%%. To ensure the error is below %.1f%%, decrease verlet-buffer-tolerance to %.0e or decrease tau_t.",
3998                         ir->verletbuf_tol, T, tau,
3999                         100*max_T_error,
4000                         100*T_error_suggest,
4001                         ir->verletbuf_tol*T_error_suggest/max_T_error);
4002                 warning(wi, warn_buf);
4003             }
4004         }
4005     }
4006
4007     if (ETC_ANDERSEN(ir->etc))
4008     {
4009         int i;
4010
4011         for (i = 0; i < ir->opts.ngtc; i++)
4012         {
4013             sprintf(err_buf, "all tau_t must currently be equal using Andersen temperature control, violated for group %d", i);
4014             CHECK(ir->opts.tau_t[0] != ir->opts.tau_t[i]);
4015             sprintf(err_buf, "all tau_t must be positive using Andersen temperature control, tau_t[%d]=%10.6f",
4016                     i, ir->opts.tau_t[i]);
4017             CHECK(ir->opts.tau_t[i] < 0);
4018         }
4019
4020         if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
4021         {
4022             for (i = 0; i < ir->opts.ngtc; i++)
4023             {
4024                 int nsteps = gmx::roundToInt(ir->opts.tau_t[i]/ir->delta_t);
4025                 sprintf(err_buf, "tau_t/delta_t for group %d for temperature control method %s must be a multiple of nstcomm (%d), as velocities of atoms in coupled groups are randomized every time step. The input tau_t (%8.3f) leads to %d steps per randomization", i, etcoupl_names[ir->etc], ir->nstcomm, ir->opts.tau_t[i], nsteps);
4026                 CHECK(nsteps % ir->nstcomm != 0);
4027             }
4028         }
4029     }
4030
4031     if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD &&
4032         ir->comm_mode == ecmNO &&
4033         !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) &&
4034         !ETC_ANDERSEN(ir->etc))
4035     {
4036         warning(wi, "You are not using center of mass motion removal (mdp option comm-mode), numerical rounding errors can lead to build up of kinetic energy of the center of mass");
4037     }
4038
4039     if (ir->epc == epcPARRINELLORAHMAN &&
4040         ir->etc == etcNOSEHOOVER)
4041     {
4042         real tau_t_max = 0;
4043         for (int g = 0; g < ir->opts.ngtc; g++)
4044         {
4045             tau_t_max = std::max(tau_t_max, ir->opts.tau_t[g]);
4046         }
4047         if (ir->tau_p < 1.9*tau_t_max)
4048         {
4049             std::string message =
4050                 gmx::formatString("With %s T-coupling and %s p-coupling, "
4051                                   "%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
4052                                   etcoupl_names[ir->etc],
4053                                   epcoupl_names[ir->epc],
4054                                   "tau-p", ir->tau_p,
4055                                   "tau-t", tau_t_max);
4056             warning(wi, message.c_str());
4057         }
4058     }
4059
4060     /* Check for pressure coupling with absolute position restraints */
4061     if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
4062     {
4063         absolute_reference(ir, sys, TRUE, AbsRef);
4064         {
4065             for (m = 0; m < DIM; m++)
4066             {
4067                 if (AbsRef[m] && norm2(ir->compress[m]) > 0)
4068                 {
4069                     warning(wi, "You are using pressure coupling with absolute position restraints, this will give artifacts. Use the refcoord_scaling option.");
4070                     break;
4071                 }
4072             }
4073         }
4074     }
4075
4076     bCharge = FALSE;
4077     aloopb  = gmx_mtop_atomloop_block_init(sys);
4078     const t_atom *atom;
4079     while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol))
4080     {
4081         if (atom->q != 0 || atom->qB != 0)
4082         {
4083             bCharge = TRUE;
4084         }
4085     }
4086
4087     if (!bCharge)
4088     {
4089         if (EEL_FULL(ir->coulombtype))
4090         {
4091             sprintf(err_buf,
4092                     "You are using full electrostatics treatment %s for a system without charges.\n"
4093                     "This costs a lot of performance for just processing zeros, consider using %s instead.\n",
4094                     EELTYPE(ir->coulombtype), EELTYPE(eelCUT));
4095             warning(wi, err_buf);
4096         }
4097     }
4098     else
4099     {
4100         if (ir->coulombtype == eelCUT && ir->rcoulomb > 0)
4101         {
4102             sprintf(err_buf,
4103                     "You are using a plain Coulomb cut-off, which might produce artifacts.\n"
4104                     "You might want to consider using %s electrostatics.\n",
4105                     EELTYPE(eelPME));
4106             warning_note(wi, err_buf);
4107         }
4108     }
4109
4110     /* Check if combination rules used in LJ-PME are the same as in the force field */
4111     if (EVDW_PME(ir->vdwtype))
4112     {
4113         check_combination_rules(ir, sys, wi);
4114     }
4115
4116     /* Generalized reaction field */
4117     if (ir->opts.ngtc == 0)
4118     {
4119         sprintf(err_buf, "No temperature coupling while using coulombtype %s",
4120                 eel_names[eelGRF]);
4121         CHECK(ir->coulombtype == eelGRF);
4122     }
4123     else
4124     {
4125         sprintf(err_buf, "When using coulombtype = %s"
4126                 " ref-t for temperature coupling should be > 0",
4127                 eel_names[eelGRF]);
4128         CHECK((ir->coulombtype == eelGRF) && (ir->opts.ref_t[0] <= 0));
4129     }
4130
4131     bAcc = FALSE;
4132     for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
4133     {
4134         for (m = 0; (m < DIM); m++)
4135         {
4136             if (fabs(ir->opts.acc[i][m]) > 1e-6)
4137             {
4138                 bAcc = TRUE;
4139             }
4140         }
4141     }
4142     if (bAcc)
4143     {
4144         clear_rvec(acc);
4145         snew(mgrp, sys->groups.grps[egcACC].nr);
4146         aloop = gmx_mtop_atomloop_all_init(sys);
4147         const t_atom *atom;
4148         while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
4149         {
4150             mgrp[getGroupType(&sys->groups, egcACC, i)] += atom->m;
4151         }
4152         mt = 0.0;
4153         for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
4154         {
4155             for (m = 0; (m < DIM); m++)
4156             {
4157                 acc[m] += ir->opts.acc[i][m]*mgrp[i];
4158             }
4159             mt += mgrp[i];
4160         }
4161         for (m = 0; (m < DIM); m++)
4162         {
4163             if (fabs(acc[m]) > 1e-6)
4164             {
4165                 const char *dim[DIM] = { "X", "Y", "Z" };
4166                 fprintf(stderr,
4167                         "Net Acceleration in %s direction, will %s be corrected\n",
4168                         dim[m], ir->nstcomm != 0 ? "" : "not");
4169                 if (ir->nstcomm != 0 && m < ndof_com(ir))
4170                 {
4171                     acc[m] /= mt;
4172                     for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
4173                     {
4174                         ir->opts.acc[i][m] -= acc[m];
4175                     }
4176                 }
4177             }
4178         }
4179         sfree(mgrp);
4180     }
4181
4182     if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0 &&
4183         !gmx_within_tol(sys->ffparams.reppow, 12.0, 10*GMX_DOUBLE_EPS))
4184     {
4185         gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12");
4186     }
4187
4188     if (ir->bPull)
4189     {
4190         bool bWarned;
4191
4192         bWarned = FALSE;
4193         for (i = 0; i < ir->pull->ncoord && !bWarned; i++)
4194         {
4195             if (ir->pull->coord[i].group[0] == 0 ||
4196                 ir->pull->coord[i].group[1] == 0)
4197             {
4198                 absolute_reference(ir, sys, FALSE, AbsRef);
4199                 for (m = 0; m < DIM; m++)
4200                 {
4201                     if (ir->pull->coord[i].dim[m] && !AbsRef[m])
4202                     {
4203                         warning(wi, "You are using an absolute reference for pulling, but the rest of the system does not have an absolute reference. This will lead to artifacts.");
4204                         bWarned = TRUE;
4205                         break;
4206                     }
4207                 }
4208             }
4209         }
4210
4211         for (i = 0; i < 3; i++)
4212         {
4213             for (m = 0; m <= i; m++)
4214             {
4215                 if ((ir->epc != epcNO && ir->compress[i][m] != 0) ||
4216                     ir->deform[i][m] != 0)
4217                 {
4218                     for (c = 0; c < ir->pull->ncoord; c++)
4219                     {
4220                         if (ir->pull->coord[c].eGeom == epullgDIRPBC &&
4221                             ir->pull->coord[c].vec[m] != 0)
4222                         {
4223                             gmx_fatal(FARGS, "Can not have dynamic box while using pull geometry '%s' (dim %c)", EPULLGEOM(ir->pull->coord[c].eGeom), 'x'+m);
4224                         }
4225                     }
4226                 }
4227             }
4228         }
4229     }
4230
4231     check_disre(sys);
4232 }
4233
4234 void double_check(t_inputrec *ir, matrix box,
4235                   bool bHasNormalConstraints,
4236                   bool bHasAnyConstraints,
4237                   warninp_t wi)
4238 {
4239     real        min_size;
4240     char        warn_buf[STRLEN];
4241     const char *ptr;
4242
4243     ptr = check_box(ir->ePBC, box);
4244     if (ptr)
4245     {
4246         warning_error(wi, ptr);
4247     }
4248
4249     if (bHasNormalConstraints && ir->eConstrAlg == econtSHAKE)
4250     {
4251         if (ir->shake_tol <= 0.0)
4252         {
4253             sprintf(warn_buf, "ERROR: shake-tol must be > 0 instead of %g\n",
4254                     ir->shake_tol);
4255             warning_error(wi, warn_buf);
4256         }
4257     }
4258
4259     if ( (ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
4260     {
4261         /* If we have Lincs constraints: */
4262         if (ir->eI == eiMD && ir->etc == etcNO &&
4263             ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
4264         {
4265             sprintf(warn_buf, "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
4266             warning_note(wi, warn_buf);
4267         }
4268
4269         if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8))
4270         {
4271             sprintf(warn_buf, "For accurate %s with LINCS constraints, lincs-order should be 8 or more.", ei_names[ir->eI]);
4272             warning_note(wi, warn_buf);
4273         }
4274         if (ir->epc == epcMTTK)
4275         {
4276             warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
4277         }
4278     }
4279
4280     if (bHasAnyConstraints && ir->epc == epcMTTK)
4281     {
4282         warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
4283     }
4284
4285     if (ir->LincsWarnAngle > 90.0)
4286     {
4287         sprintf(warn_buf, "lincs-warnangle can not be larger than 90 degrees, setting it to 90.\n");
4288         warning(wi, warn_buf);
4289         ir->LincsWarnAngle = 90.0;
4290     }
4291
4292     if (ir->ePBC != epbcNONE)
4293     {
4294         if (ir->nstlist == 0)
4295         {
4296             warning(wi, "With nstlist=0 atoms are only put into the box at step 0, therefore drifting atoms might cause the simulation to crash.");
4297         }
4298         if (ir->ns_type == ensGRID)
4299         {
4300             if (gmx::square(ir->rlist) >= max_cutoff2(ir->ePBC, box))
4301             {
4302                 sprintf(warn_buf, "ERROR: The cut-off length is longer than half the shortest box vector or longer than the smallest box diagonal element. Increase the box size or decrease rlist.\n");
4303                 warning_error(wi, warn_buf);
4304             }
4305         }
4306         else
4307         {
4308             min_size = std::min(box[XX][XX], std::min(box[YY][YY], box[ZZ][ZZ]));
4309             if (2*ir->rlist >= min_size)
4310             {
4311                 sprintf(warn_buf, "ERROR: One of the box lengths is smaller than twice the cut-off length. Increase the box size or decrease rlist.");
4312                 warning_error(wi, warn_buf);
4313                 if (TRICLINIC(box))
4314                 {
4315                     fprintf(stderr, "Grid search might allow larger cut-off's than simple search with triclinic boxes.");
4316                 }
4317             }
4318         }
4319     }
4320 }
4321
4322 void check_chargegroup_radii(const gmx_mtop_t *mtop, const t_inputrec *ir,
4323                              rvec *x,
4324                              warninp_t wi)
4325 {
4326     real rvdw1, rvdw2, rcoul1, rcoul2;
4327     char warn_buf[STRLEN];
4328
4329     calc_chargegroup_radii(mtop, x, &rvdw1, &rvdw2, &rcoul1, &rcoul2);
4330
4331     if (rvdw1 > 0)
4332     {
4333         printf("Largest charge group radii for Van der Waals: %5.3f, %5.3f nm\n",
4334                rvdw1, rvdw2);
4335     }
4336     if (rcoul1 > 0)
4337     {
4338         printf("Largest charge group radii for Coulomb:       %5.3f, %5.3f nm\n",
4339                rcoul1, rcoul2);
4340     }
4341
4342     if (ir->rlist > 0)
4343     {
4344         if (rvdw1  + rvdw2  > ir->rlist ||
4345             rcoul1 + rcoul2 > ir->rlist)
4346         {
4347             sprintf(warn_buf,
4348                     "The sum of the two largest charge group radii (%f) "
4349                     "is larger than rlist (%f)\n",
4350                     std::max(rvdw1+rvdw2, rcoul1+rcoul2), ir->rlist);
4351             warning(wi, warn_buf);
4352         }
4353         else
4354         {
4355             /* Here we do not use the zero at cut-off macro,
4356              * since user defined interactions might purposely
4357              * not be zero at the cut-off.
4358              */
4359             if (ir_vdw_is_zero_at_cutoff(ir) &&
4360                 rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
4361             {
4362                 sprintf(warn_buf, "The sum of the two largest charge group "
4363                         "radii (%f) is larger than rlist (%f) - rvdw (%f).\n"
4364                         "With exact cut-offs, better performance can be "
4365                         "obtained with cutoff-scheme = %s, because it "
4366                         "does not use charge groups at all.",
4367                         rvdw1+rvdw2,
4368                         ir->rlist, ir->rvdw,
4369                         ecutscheme_names[ecutsVERLET]);
4370                 if (ir_NVE(ir))
4371                 {
4372                     warning(wi, warn_buf);
4373                 }
4374                 else
4375                 {
4376                     warning_note(wi, warn_buf);
4377                 }
4378             }
4379             if (ir_coulomb_is_zero_at_cutoff(ir) &&
4380                 rcoul1 + rcoul2 > ir->rlist - ir->rcoulomb)
4381             {
4382                 sprintf(warn_buf, "The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rcoulomb (%f).\n"
4383                         "With exact cut-offs, better performance can be obtained with cutoff-scheme = %s, because it does not use charge groups at all.",
4384                         rcoul1+rcoul2,
4385                         ir->rlist, ir->rcoulomb,
4386                         ecutscheme_names[ecutsVERLET]);
4387                 if (ir_NVE(ir))
4388                 {
4389                     warning(wi, warn_buf);
4390                 }
4391                 else
4392                 {
4393                     warning_note(wi, warn_buf);
4394                 }
4395             }
4396         }
4397     }
4398 }