Add C++ version of t_ilist
[gromacs.git] / src / gromacs / gmxpreprocess / readir.cpp
blobb27b707f1bc93c3b9e968244fdf88909b6e92493
1 /*
2 * This file is part of the GROMACS molecular simulation package.
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.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
37 #include "gmxpre.h"
39 #include "readir.h"
41 #include <cctype>
42 #include <climits>
43 #include <cmath>
44 #include <cstdlib>
46 #include <algorithm>
47 #include <string>
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"
88 #define MAXPTR 254
89 #define NOGID 255
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.
98 typedef struct t_inputrec_strings
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];
116 } gmx_inputrec_strings;
118 static gmx_inputrec_strings *is = nullptr;
120 void init_inputrec_strings()
122 if (is)
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.");
126 snew(is, 1);
129 void done_inputrec_strings()
131 sfree(is);
132 is = nullptr;
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. */
146 static const char *constraints[eshNR+1] = {
147 "none", "h-bonds", "all-bonds", "h-angles", "all-angles", nullptr
150 static const char *couple_lam[ecouplamNR+1] = {
151 "vdw-q", "vdw", "q", "none", nullptr
154 static void GetSimTemps(int ntemps, t_simtemp *simtemp, double *temperature_lambdas)
157 int i;
159 for (i = 0; i < ntemps; i++)
161 /* simple linear scaling -- allows more control */
162 if (simtemp->eSimTempScale == esimtempLINEAR)
164 simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*temperature_lambdas[i];
166 else if (simtemp->eSimTempScale == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */
168 simtemp->temperatures[i] = simtemp->simtemp_low * std::pow(simtemp->simtemp_high/simtemp->simtemp_low, static_cast<real>((1.0*i)/(ntemps-1)));
170 else if (simtemp->eSimTempScale == esimtempEXPONENTIAL)
172 simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*(std::expm1(temperature_lambdas[i])/std::expm1(1.0));
174 else
176 char errorstr[128];
177 sprintf(errorstr, "eSimTempScale=%d not defined", simtemp->eSimTempScale);
178 gmx_fatal(FARGS, "%s", errorstr);
185 static void _low_check(bool b, const char *s, warninp_t wi)
187 if (b)
189 warning_error(wi, s);
193 static void check_nst(const char *desc_nst, int nst,
194 const char *desc_p, int *p,
195 warninp_t wi)
197 char buf[STRLEN];
199 if (*p > 0 && *p % nst != 0)
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);
209 static bool ir_NVE(const t_inputrec *ir)
211 return (EI_MD(ir->eI) && ir->etc == etcNO);
214 static int lcd(int n1, int n2)
216 int d, i;
218 d = 1;
219 for (i = 2; (i <= n1 && i <= n2); i++)
221 if (n1 % i == 0 && n2 % i == 0)
223 d = i;
227 return d;
230 static void process_interaction_modifier(const t_inputrec *ir, int *eintmod)
232 if (*eintmod == eintmodPOTSHIFT_VERLET)
234 if (ir->cutoff_scheme == ecutsVERLET)
236 *eintmod = eintmodPOTSHIFT;
238 else
240 *eintmod = eintmodNONE;
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
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.
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;
263 set_warning_line(wi, mdparin, -1);
265 if (ir->coulombtype == eelRF_NEC_UNSUPPORTED)
267 sprintf(warn_buf, "%s electrostatics is no longer supported",
268 eel_names[eelRF_NEC_UNSUPPORTED]);
269 warning_error(wi, warn_buf);
272 /* BASIC CUT-OFF STUFF */
273 if (ir->rcoulomb < 0)
275 warning_error(wi, "rcoulomb should be >= 0");
277 if (ir->rvdw < 0)
279 warning_error(wi, "rvdw should be >= 0");
281 if (ir->rlist < 0 &&
282 !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0))
284 warning_error(wi, "rlist should be >= 0");
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);
289 process_interaction_modifier(ir, &ir->coulomb_modifier);
290 process_interaction_modifier(ir, &ir->vdw_modifier);
292 if (ir->cutoff_scheme == ecutsGROUP)
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.");
299 if (ir->rlist > 0 && ir->rlist < ir->rcoulomb)
301 gmx_fatal(FARGS, "rcoulomb must not be greater than rlist (twin-range schemes are not supported)");
303 if (ir->rlist > 0 && ir->rlist < ir->rvdw)
305 gmx_fatal(FARGS, "rvdw must not be greater than rlist (twin-range schemes are not supported)");
308 if (ir->rlist == 0 && ir->ePBC != epbcNONE)
310 warning_error(wi, "Can not have an infinite cut-off with PBC");
314 if (ir->cutoff_scheme == ecutsVERLET)
316 real rc_max;
318 /* Normal Verlet type neighbor-list, currently only limited feature support */
319 if (inputrec2nboundeddim(ir) < 3)
321 warning_error(wi, "With Verlet lists only full pbc or pbc=xy with walls is supported");
324 // We don't (yet) have general Verlet kernels for rcoulomb!=rvdw
325 if (ir->rcoulomb != ir->rvdw)
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)
334 warning_error(wi, "With Verlet lists rcoulomb!=rvdw is not supported (except for rcoulomb>rvdw with PME electrostatics)");
338 if (ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwSWITCH)
340 if (ir->vdw_modifier == eintmodNONE ||
341 ir->vdw_modifier == eintmodPOTSHIFT)
343 ir->vdw_modifier = (ir->vdwtype == evdwSHIFT ? eintmodFORCESWITCH : eintmodPOTSWITCH);
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);
348 ir->vdwtype = evdwCUT;
350 else
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);
357 if (!(ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME))
359 warning_error(wi, "With Verlet lists only cut-off and PME LJ interactions are supported");
361 if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) ||
362 EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD))
364 warning_error(wi, "With Verlet lists only cut-off, reaction-field, PME and Ewald electrostatics are supported");
366 if (!(ir->coulomb_modifier == eintmodNONE ||
367 ir->coulomb_modifier == eintmodPOTSHIFT))
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);
373 if (EEL_USER(ir->coulombtype))
375 sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme", eel_names[ir->coulombtype]);
376 warning_error(wi, warn_buf);
379 if (ir->nstlist <= 0)
381 warning_error(wi, "With Verlet lists nstlist should be larger than 0");
384 if (ir->nstlist < 10)
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.");
389 rc_max = std::max(ir->rvdw, ir->rcoulomb);
391 if (ir->verletbuf_tol <= 0)
393 if (ir->verletbuf_tol == 0)
395 warning_error(wi, "Can not have Verlet buffer tolerance of exactly 0");
398 if (ir->rlist < rc_max)
400 warning_error(wi, "With verlet lists rlist can not be smaller than rvdw or rcoulomb");
403 if (ir->rlist == rc_max && ir->nstlist > 1)
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.");
408 else
410 if (ir->rlist > rc_max)
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.");
415 if (ir->nstlist == 1)
417 /* No buffer required */
418 ir->rlist = rc_max;
420 else
422 if (EI_DYNAMICS(ir->eI))
424 if (inputrec2nboundeddim(ir) < 3)
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.");
428 /* Set rlist temporarily so we can continue processing */
429 ir->rlist = rc_max;
431 else
433 /* Set the buffer to 5% of the cut-off */
434 ir->rlist = (1.0 + verlet_buffer_ratio_nodynamics)*rc_max;
440 /* GENERAL INTEGRATOR STUFF */
441 if (!EI_MD(ir->eI))
443 if (ir->etc != etcNO)
445 if (EI_RANDOM(ir->eI))
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]);
449 else
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]);
453 warning_note(wi, warn_buf);
455 ir->etc = etcNO;
457 if (ir->eI == eiVVAK)
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);
462 if (!EI_DYNAMICS(ir->eI))
464 if (ir->epc != epcNO)
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);
469 ir->epc = epcNO;
471 if (EI_DYNAMICS(ir->eI))
473 if (ir->nstcalcenergy < 0)
475 ir->nstcalcenergy = ir_optimal_nstcalcenergy(ir);
476 if (ir->nstenergy != 0 && ir->nstenergy < ir->nstcalcenergy)
478 /* nstcalcenergy larger than nstener does not make sense.
479 * We ideally want nstcalcenergy=nstener.
481 if (ir->nstlist > 0)
483 ir->nstcalcenergy = lcd(ir->nstenergy, ir->nstlist);
485 else
487 ir->nstcalcenergy = ir->nstenergy;
491 else if ( (ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy) ||
492 (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
493 (ir->nstcalcenergy > ir->fepvals->nstdhdl) ) )
496 const char *nsten = "nstenergy";
497 const char *nstdh = "nstdhdl";
498 const char *min_name = nsten;
499 int min_nst = ir->nstenergy;
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))
505 min_nst = ir->fepvals->nstdhdl;
506 min_name = nstdh;
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;
516 if (ir->epc != epcNO)
518 if (ir->nstpcouple < 0)
520 ir->nstpcouple = ir_optimal_nstpcouple(ir);
524 if (ir->nstcalcenergy > 0)
526 if (ir->efep != efepNO)
528 /* nstdhdl should be a multiple of nstcalcenergy */
529 check_nst("nstcalcenergy", ir->nstcalcenergy,
530 "nstdhdl", &ir->fepvals->nstdhdl, wi);
531 /* nstexpanded should be a multiple of nstcalcenergy */
532 check_nst("nstcalcenergy", ir->nstcalcenergy,
533 "nstexpanded", &ir->expandedvals->nstexpanded, wi);
535 /* for storing exact averages nstenergy should be
536 * a multiple of nstcalcenergy
538 check_nst("nstcalcenergy", ir->nstcalcenergy,
539 "nstenergy", &ir->nstenergy, wi);
543 if (ir->nsteps == 0 && !ir->bContinuation)
545 warning_note(wi, "For a correct single-point energy evaluation with nsteps = 0, use continuation = yes to avoid constraining the input coordinates.");
548 /* LD STUFF */
549 if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
550 ir->bContinuation && ir->ld_seed != -1)
552 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)");
555 /* TPI STUFF */
556 if (EI_TPI(ir->eI))
558 sprintf(err_buf, "TPI only works with pbc = %s", epbc_names[epbcXYZ]);
559 CHECK(ir->ePBC != epbcXYZ);
560 sprintf(err_buf, "TPI only works with ns = %s", ens_names[ensGRID]);
561 CHECK(ir->ns_type != ensGRID);
562 sprintf(err_buf, "with TPI nstlist should be larger than zero");
563 CHECK(ir->nstlist <= 0);
564 sprintf(err_buf, "TPI does not work with full electrostatics other than PME");
565 CHECK(EEL_FULL(ir->coulombtype) && !EEL_PME(ir->coulombtype));
566 sprintf(err_buf, "TPI does not work (yet) with the Verlet cut-off scheme");
567 CHECK(ir->cutoff_scheme == ecutsVERLET);
570 /* SHAKE / LINCS */
571 if ( (opts->nshake > 0) && (opts->bMorse) )
573 sprintf(warn_buf,
574 "Using morse bond-potentials while constraining bonds is useless");
575 warning(wi, warn_buf);
578 if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
579 ir->bContinuation && ir->ld_seed != -1)
581 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)");
583 /* verify simulated tempering options */
585 if (ir->bSimTemp)
587 bool bAllTempZero = TRUE;
588 for (i = 0; i < fep->n_lambda; i++)
590 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]);
591 CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
592 if (fep->all_lambda[efptTEMPERATURE][i] > 0)
594 bAllTempZero = FALSE;
597 sprintf(err_buf, "if simulated tempering is on, temperature-lambdas may not be all zero");
598 CHECK(bAllTempZero == TRUE);
600 sprintf(err_buf, "Simulated tempering is currently only compatible with md-vv");
601 CHECK(ir->eI != eiVV);
603 /* check compatability of the temperature coupling with simulated tempering */
605 if (ir->etc == etcNOSEHOOVER)
607 sprintf(warn_buf, "Nose-Hoover based temperature control such as [%s] my not be entirelyconsistent with simulated tempering", etcoupl_names[ir->etc]);
608 warning_note(wi, warn_buf);
611 /* check that the temperatures make sense */
613 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);
614 CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low);
616 sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_high);
617 CHECK(ir->simtempvals->simtemp_high <= 0);
619 sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_low);
620 CHECK(ir->simtempvals->simtemp_low <= 0);
623 /* verify free energy options */
625 if (ir->efep != efepNO)
627 fep = ir->fepvals;
628 sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2",
629 fep->sc_power);
630 CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2);
632 sprintf(err_buf, "The soft-core sc-r-power is %d and can only be 6 or 48",
633 static_cast<int>(fep->sc_r_power));
634 CHECK(fep->sc_alpha != 0 && fep->sc_r_power != 6.0 && fep->sc_r_power != 48.0);
636 sprintf(err_buf, "Can't use positive delta-lambda (%g) if initial state/lambda does not start at zero", fep->delta_lambda);
637 CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0)));
639 sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations", fep->delta_lambda);
640 CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
642 sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)");
643 CHECK(!(EI_VV(ir->eI)) && (ir->efep == efepEXPANDED));
645 sprintf(err_buf, "Free-energy not implemented for Ewald");
646 CHECK(ir->coulombtype == eelEWALD);
648 /* check validty of lambda inputs */
649 if (fep->n_lambda == 0)
651 /* Clear output in case of no states:*/
652 sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state);
653 CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0));
655 else
657 sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d", fep->init_fep_state, fep->n_lambda-1);
658 CHECK((fep->init_fep_state >= fep->n_lambda));
661 sprintf(err_buf, "Lambda state must be set, either with init-lambda-state or with init-lambda");
662 CHECK((fep->init_fep_state < 0) && (fep->init_lambda < 0));
664 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",
665 fep->init_lambda, fep->init_fep_state);
666 CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
670 if ((fep->init_lambda >= 0) && (fep->delta_lambda == 0))
672 int n_lambda_terms;
673 n_lambda_terms = 0;
674 for (i = 0; i < efptNR; i++)
676 if (fep->separate_dvdl[i])
678 n_lambda_terms++;
681 if (n_lambda_terms > 1)
683 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.");
684 warning(wi, warn_buf);
687 if (n_lambda_terms < 2 && fep->n_lambda > 0)
689 warning_note(wi,
690 "init-lambda is deprecated for setting lambda state (except for slow growth). Use init-lambda-state instead.");
694 for (j = 0; j < efptNR; j++)
696 for (i = 0; i < fep->n_lambda; i++)
698 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]);
699 CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
703 if ((fep->sc_alpha > 0) && (!fep->bScCoul))
705 for (i = 0; i < fep->n_lambda; i++)
707 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],
708 fep->all_lambda[efptCOUL][i]);
709 CHECK((fep->sc_alpha > 0) &&
710 (((fep->all_lambda[efptCOUL][i] > 0.0) &&
711 (fep->all_lambda[efptCOUL][i] < 1.0)) &&
712 ((fep->all_lambda[efptVDW][i] > 0.0) &&
713 (fep->all_lambda[efptVDW][i] < 1.0))));
717 if ((fep->bScCoul) && (EEL_PME(ir->coulombtype)))
719 real sigma, lambda, r_sc;
721 sigma = 0.34;
722 /* Maximum estimate for A and B charges equal with lambda power 1 */
723 lambda = 0.5;
724 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);
725 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.",
726 fep->sc_r_power,
727 sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
728 warning_note(wi, warn_buf);
731 /* Free Energy Checks -- In an ideal world, slow growth and FEP would
732 be treated differently, but that's the next step */
734 for (i = 0; i < efptNR; i++)
736 for (j = 0; j < fep->n_lambda; j++)
738 sprintf(err_buf, "%s[%d] must be between 0 and 1", efpt_names[i], j);
739 CHECK((fep->all_lambda[i][j] < 0) || (fep->all_lambda[i][j] > 1));
744 if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
746 fep = ir->fepvals;
748 /* checking equilibration of weights inputs for validity */
750 sprintf(err_buf, "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal to %s",
751 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
752 CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
754 sprintf(err_buf, "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to %s",
755 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
756 CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
758 sprintf(err_buf, "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
759 expand->equil_steps, elmceq_names[elmceqSTEPS]);
760 CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
762 sprintf(err_buf, "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
763 expand->equil_samples, elmceq_names[elmceqWLDELTA]);
764 CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
766 sprintf(err_buf, "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
767 expand->equil_ratio, elmceq_names[elmceqRATIO]);
768 CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
770 sprintf(err_buf, "weight-equil-number-all-lambda (%d) must be a positive integer if lmc-weights-equil=%s",
771 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
772 CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
774 sprintf(err_buf, "weight-equil-number-samples (%d) must be a positive integer if lmc-weights-equil=%s",
775 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
776 CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
778 sprintf(err_buf, "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
779 expand->equil_steps, elmceq_names[elmceqSTEPS]);
780 CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
782 sprintf(err_buf, "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
783 expand->equil_wl_delta, elmceq_names[elmceqWLDELTA]);
784 CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
786 sprintf(err_buf, "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
787 expand->equil_ratio, elmceq_names[elmceqRATIO]);
788 CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
790 sprintf(err_buf, "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
791 elmceq_names[elmceqWLDELTA], elamstats_names[elamstatsWL], elamstats_names[elamstatsWWL]);
792 CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
794 sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
795 CHECK((expand->lmc_repeats <= 0));
796 sprintf(err_buf, "minimum-var-min (%d) must be greater than 0", expand->minvarmin);
797 CHECK((expand->minvarmin <= 0));
798 sprintf(err_buf, "weight-c-range (%d) must be greater or equal to 0", expand->c_range);
799 CHECK((expand->c_range < 0));
800 sprintf(err_buf, "init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != 'no'",
801 fep->init_fep_state, expand->lmc_forced_nstart);
802 CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0) && (expand->elmcmove != elmcmoveNO));
803 sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
804 CHECK((expand->lmc_forced_nstart < 0));
805 sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)", fep->init_fep_state);
806 CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda));
808 sprintf(err_buf, "init-wl-delta (%f) must be greater than or equal to 0", expand->init_wl_delta);
809 CHECK((expand->init_wl_delta < 0));
810 sprintf(err_buf, "wl-ratio (%f) must be between 0 and 1", expand->wl_ratio);
811 CHECK((expand->wl_ratio <= 0) || (expand->wl_ratio >= 1));
812 sprintf(err_buf, "wl-scale (%f) must be between 0 and 1", expand->wl_scale);
813 CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1));
815 /* if there is no temperature control, we need to specify an MC temperature */
816 if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO) && (expand->mc_temp <= 0.0))
818 sprintf(err_buf, "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set to a positive number");
819 warning_error(wi, err_buf);
821 if (expand->nstTij > 0)
823 sprintf(err_buf, "nstlog must be non-zero");
824 CHECK(ir->nstlog == 0);
825 sprintf(err_buf, "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
826 expand->nstTij, ir->nstlog);
827 CHECK((expand->nstTij % ir->nstlog) != 0);
831 /* PBC/WALLS */
832 sprintf(err_buf, "walls only work with pbc=%s", epbc_names[epbcXY]);
833 CHECK(ir->nwall && ir->ePBC != epbcXY);
835 /* VACUUM STUFF */
836 if (ir->ePBC != epbcXYZ && ir->nwall != 2)
838 if (ir->ePBC == epbcNONE)
840 if (ir->epc != epcNO)
842 warning(wi, "Turning off pressure coupling for vacuum system");
843 ir->epc = epcNO;
846 else
848 sprintf(err_buf, "Can not have pressure coupling with pbc=%s",
849 epbc_names[ir->ePBC]);
850 CHECK(ir->epc != epcNO);
852 sprintf(err_buf, "Can not have Ewald with pbc=%s", epbc_names[ir->ePBC]);
853 CHECK(EEL_FULL(ir->coulombtype));
855 sprintf(err_buf, "Can not have dispersion correction with pbc=%s",
856 epbc_names[ir->ePBC]);
857 CHECK(ir->eDispCorr != edispcNO);
860 if (ir->rlist == 0.0)
862 sprintf(err_buf, "can only have neighborlist cut-off zero (=infinite)\n"
863 "with coulombtype = %s or coulombtype = %s\n"
864 "without periodic boundary conditions (pbc = %s) and\n"
865 "rcoulomb and rvdw set to zero",
866 eel_names[eelCUT], eel_names[eelUSER], epbc_names[epbcNONE]);
867 CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER)) ||
868 (ir->ePBC != epbcNONE) ||
869 (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0));
871 if (ir->nstlist > 0)
873 warning_note(wi, "Simulating without cut-offs can be (slightly) faster with nstlist=0, nstype=simple and only one MPI rank");
877 /* COMM STUFF */
878 if (ir->nstcomm == 0)
880 ir->comm_mode = ecmNO;
882 if (ir->comm_mode != ecmNO)
884 if (ir->nstcomm < 0)
886 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");
887 ir->nstcomm = abs(ir->nstcomm);
890 if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy)
892 warning_note(wi, "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting nstcomm to nstcalcenergy");
893 ir->nstcomm = ir->nstcalcenergy;
896 if (ir->comm_mode == ecmANGULAR)
898 sprintf(err_buf, "Can not remove the rotation around the center of mass with periodic molecules");
899 CHECK(ir->bPeriodicMols);
900 if (ir->ePBC != epbcNONE)
902 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.");
907 if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->ePBC == epbcNONE && ir->comm_mode != ecmANGULAR)
909 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]);
910 warning_note(wi, warn_buf);
913 /* TEMPERATURE COUPLING */
914 if (ir->etc == etcYES)
916 ir->etc = etcBERENDSEN;
917 warning_note(wi, "Old option for temperature coupling given: "
918 "changing \"yes\" to \"Berendsen\"\n");
921 if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
923 if (ir->opts.nhchainlength < 1)
925 sprintf(warn_buf, "number of Nose-Hoover chains (currently %d) cannot be less than 1,reset to 1\n", ir->opts.nhchainlength);
926 ir->opts.nhchainlength = 1;
927 warning(wi, warn_buf);
930 if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
932 warning_note(wi, "leapfrog does not yet support Nose-Hoover chains, nhchainlength reset to 1");
933 ir->opts.nhchainlength = 1;
936 else
938 ir->opts.nhchainlength = 0;
941 if (ir->eI == eiVVAK)
943 sprintf(err_buf, "%s implemented primarily for validation, and requires nsttcouple = 1 and nstpcouple = 1.",
944 ei_names[eiVVAK]);
945 CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1));
948 if (ETC_ANDERSEN(ir->etc))
950 sprintf(err_buf, "%s temperature control not supported for integrator %s.", etcoupl_names[ir->etc], ei_names[ir->eI]);
951 CHECK(!(EI_VV(ir->eI)));
953 if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
955 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]);
956 warning_note(wi, warn_buf);
959 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]);
960 CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
963 if (ir->etc == etcBERENDSEN)
965 sprintf(warn_buf, "The %s thermostat does not generate the correct kinetic energy distribution. You might want to consider using the %s thermostat.",
966 ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
967 warning_note(wi, warn_buf);
970 if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc))
971 && ir->epc == epcBERENDSEN)
973 sprintf(warn_buf, "Using Berendsen pressure coupling invalidates the "
974 "true ensemble for the thermostat");
975 warning(wi, warn_buf);
978 /* PRESSURE COUPLING */
979 if (ir->epc == epcISOTROPIC)
981 ir->epc = epcBERENDSEN;
982 warning_note(wi, "Old option for pressure coupling given: "
983 "changing \"Isotropic\" to \"Berendsen\"\n");
986 if (ir->epc != epcNO)
988 dt_pcoupl = ir->nstpcouple*ir->delta_t;
990 sprintf(err_buf, "tau-p must be > 0 instead of %g\n", ir->tau_p);
991 CHECK(ir->tau_p <= 0);
993 if (ir->tau_p/dt_pcoupl < pcouple_min_integration_steps(ir->epc) - 10*GMX_REAL_EPS)
995 sprintf(warn_buf, "For proper integration of the %s barostat, tau-p (%g) should be at least %d times larger than nstpcouple*dt (%g)",
996 EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl);
997 warning(wi, warn_buf);
1000 sprintf(err_buf, "compressibility must be > 0 when using pressure"
1001 " coupling %s\n", EPCOUPLTYPE(ir->epc));
1002 CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 ||
1003 ir->compress[ZZ][ZZ] < 0 ||
1004 (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 &&
1005 ir->compress[ZZ][XX] <= 0 && ir->compress[ZZ][YY] <= 0));
1007 if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
1009 sprintf(warn_buf,
1010 "You are generating velocities so I am assuming you "
1011 "are equilibrating a system. You are using "
1012 "%s pressure coupling, but this can be "
1013 "unstable for equilibration. If your system crashes, try "
1014 "equilibrating first with Berendsen pressure coupling. If "
1015 "you are not equilibrating the system, you can probably "
1016 "ignore this warning.",
1017 epcoupl_names[ir->epc]);
1018 warning(wi, warn_buf);
1022 if (EI_VV(ir->eI))
1024 if (ir->epc > epcNO)
1026 if ((ir->epc != epcBERENDSEN) && (ir->epc != epcMTTK))
1028 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 else
1034 if (ir->epc == epcMTTK)
1036 warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
1040 /* ELECTROSTATICS */
1041 /* More checks are in triple check (grompp.c) */
1043 if (ir->coulombtype == eelSWITCH)
1045 sprintf(warn_buf, "coulombtype = %s is only for testing purposes and can lead to serious "
1046 "artifacts, advice: use coulombtype = %s",
1047 eel_names[ir->coulombtype],
1048 eel_names[eelRF_ZERO]);
1049 warning(wi, warn_buf);
1052 if (EEL_RF(ir->coulombtype) && ir->epsilon_rf == 1 && ir->epsilon_r != 1)
1054 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);
1055 warning(wi, warn_buf);
1056 ir->epsilon_rf = ir->epsilon_r;
1057 ir->epsilon_r = 1.0;
1060 if (ir->epsilon_r == 0)
1062 sprintf(err_buf,
1063 "It is pointless to use long-range electrostatics with infinite relative permittivity."
1064 "Since you are effectively turning of electrostatics, a plain cutoff will be much faster.");
1065 CHECK(EEL_FULL(ir->coulombtype));
1068 if (getenv("GMX_DO_GALACTIC_DYNAMICS") == nullptr)
1070 sprintf(err_buf, "epsilon-r must be >= 0 instead of %g\n", ir->epsilon_r);
1071 CHECK(ir->epsilon_r < 0);
1074 if (EEL_RF(ir->coulombtype))
1076 /* reaction field (at the cut-off) */
1078 if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0)
1080 sprintf(warn_buf, "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0",
1081 eel_names[ir->coulombtype]);
1082 warning(wi, warn_buf);
1083 ir->epsilon_rf = 0.0;
1086 sprintf(err_buf, "epsilon-rf must be >= epsilon-r");
1087 CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) ||
1088 (ir->epsilon_r == 0));
1089 if (ir->epsilon_rf == ir->epsilon_r)
1091 sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense",
1092 eel_names[ir->coulombtype]);
1093 warning(wi, warn_buf);
1096 /* Allow rlist>rcoulomb for tabulated long range stuff. This just
1097 * means the interaction is zero outside rcoulomb, but it helps to
1098 * provide accurate energy conservation.
1100 if (ir_coulomb_might_be_zero_at_cutoff(ir))
1102 if (ir_coulomb_switched(ir))
1104 sprintf(err_buf,
1105 "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the potential modifier options!",
1106 eel_names[ir->coulombtype]);
1107 CHECK(ir->rcoulomb_switch >= ir->rcoulomb);
1110 else if (ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype))
1112 if (ir->cutoff_scheme == ecutsGROUP && ir->coulomb_modifier == eintmodNONE)
1114 sprintf(err_buf, "With coulombtype = %s, rcoulomb should be >= rlist unless you use a potential modifier",
1115 eel_names[ir->coulombtype]);
1116 CHECK(ir->rlist > ir->rcoulomb);
1120 if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT)
1122 sprintf(err_buf,
1123 "Explicit switch/shift coulomb interactions cannot be used in combination with a secondary coulomb-modifier.");
1124 CHECK( ir->coulomb_modifier != eintmodNONE);
1126 if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1128 sprintf(err_buf,
1129 "Explicit switch/shift vdw interactions cannot be used in combination with a secondary vdw-modifier.");
1130 CHECK( ir->vdw_modifier != eintmodNONE);
1133 if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT ||
1134 ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1136 sprintf(warn_buf,
1137 "The switch/shift interaction settings are just for compatibility; you will get better "
1138 "performance from applying potential modifiers to your interactions!\n");
1139 warning_note(wi, warn_buf);
1142 if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH)
1144 if (ir->rcoulomb_switch/ir->rcoulomb < 0.9499)
1146 real percentage = 100*(ir->rcoulomb-ir->rcoulomb_switch)/ir->rcoulomb;
1147 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.",
1148 percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol);
1149 warning(wi, warn_buf);
1153 if (ir->vdwtype == evdwSWITCH || ir->vdw_modifier == eintmodPOTSWITCH)
1155 if (ir->rvdw_switch == 0)
1157 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.");
1158 warning(wi, warn_buf);
1162 if (EEL_FULL(ir->coulombtype))
1164 if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER ||
1165 ir->coulombtype == eelPMEUSERSWITCH)
1167 sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist",
1168 eel_names[ir->coulombtype]);
1169 CHECK(ir->rcoulomb > ir->rlist);
1171 else if (ir->cutoff_scheme == ecutsGROUP && ir->coulomb_modifier == eintmodNONE)
1173 if (ir->coulombtype == eelPME || ir->coulombtype == eelP3M_AD)
1175 sprintf(err_buf,
1176 "With coulombtype = %s (without modifier), rcoulomb must be equal to rlist.\n"
1177 "For optimal energy conservation,consider using\n"
1178 "a potential modifier.", eel_names[ir->coulombtype]);
1179 CHECK(ir->rcoulomb != ir->rlist);
1184 if (EEL_PME(ir->coulombtype) || EVDW_PME(ir->vdwtype))
1186 // TODO: Move these checks into the ewald module with the options class
1187 int orderMin = 3;
1188 int orderMax = (ir->coulombtype == eelP3M_AD ? 8 : 12);
1190 if (ir->pme_order < orderMin || ir->pme_order > orderMax)
1192 sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d", eel_names[ir->coulombtype], orderMin, orderMax);
1193 warning_error(wi, warn_buf);
1197 if (ir->nwall == 2 && EEL_FULL(ir->coulombtype))
1199 if (ir->ewald_geometry == eewg3D)
1201 sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s",
1202 epbc_names[ir->ePBC], eewg_names[eewg3DC]);
1203 warning(wi, warn_buf);
1205 /* This check avoids extra pbc coding for exclusion corrections */
1206 sprintf(err_buf, "wall-ewald-zfac should be >= 2");
1207 CHECK(ir->wall_ewald_zfac < 2);
1209 if ((ir->ewald_geometry == eewg3DC) && (ir->ePBC != epbcXY) &&
1210 EEL_FULL(ir->coulombtype))
1212 sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s",
1213 eel_names[ir->coulombtype], eewg_names[eewg3DC], epbc_names[epbcXY]);
1214 warning(wi, warn_buf);
1216 if ((ir->epsilon_surface != 0) && EEL_FULL(ir->coulombtype))
1218 if (ir->cutoff_scheme == ecutsVERLET)
1220 sprintf(warn_buf, "Since molecules/charge groups are broken using the Verlet scheme, you can not use a dipole correction to the %s electrostatics.",
1221 eel_names[ir->coulombtype]);
1222 warning(wi, warn_buf);
1224 else
1226 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",
1227 eel_names[ir->coulombtype]);
1228 warning_note(wi, warn_buf);
1232 if (ir_vdw_switched(ir))
1234 sprintf(err_buf, "With switched vdw forces or potentials, rvdw-switch must be < rvdw");
1235 CHECK(ir->rvdw_switch >= ir->rvdw);
1237 if (ir->rvdw_switch < 0.5*ir->rvdw)
1239 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.",
1240 ir->rvdw_switch, ir->rvdw);
1241 warning_note(wi, warn_buf);
1244 else if (ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME)
1246 if (ir->cutoff_scheme == ecutsGROUP && ir->vdw_modifier == eintmodNONE)
1248 sprintf(err_buf, "With vdwtype = %s, rvdw must be >= rlist unless you use a potential modifier", evdw_names[ir->vdwtype]);
1249 CHECK(ir->rlist > ir->rvdw);
1253 if (ir->vdwtype == evdwPME)
1255 if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
1257 sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s",
1258 evdw_names[ir->vdwtype],
1259 eintmod_names[eintmodPOTSHIFT],
1260 eintmod_names[eintmodNONE]);
1261 warning_error(wi, err_buf);
1265 if (ir->cutoff_scheme == ecutsGROUP)
1267 if (((ir->coulomb_modifier != eintmodNONE && ir->rcoulomb == ir->rlist) ||
1268 (ir->vdw_modifier != eintmodNONE && ir->rvdw == ir->rlist)))
1270 warning_note(wi, "With exact cut-offs, rlist should be "
1271 "larger than rcoulomb and rvdw, so that there "
1272 "is a buffer region for particle motion "
1273 "between neighborsearch steps");
1276 if (ir_coulomb_is_zero_at_cutoff(ir) && ir->rlist <= ir->rcoulomb)
1278 sprintf(warn_buf, "For energy conservation with switch/shift potentials, rlist should be 0.1 to 0.3 nm larger than rcoulomb.");
1279 warning_note(wi, warn_buf);
1281 if (ir_vdw_switched(ir) && (ir->rlist <= ir->rvdw))
1283 sprintf(warn_buf, "For energy conservation with switch/shift potentials, rlist should be 0.1 to 0.3 nm larger than rvdw.");
1284 warning_note(wi, warn_buf);
1288 if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO)
1290 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.");
1293 if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT)
1294 && ir->rvdw != 0)
1296 warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off.");
1299 if (ir->eI == eiLBFGS && ir->nbfgscorr <= 0)
1301 warning(wi, "Using L-BFGS with nbfgscorr<=0 just gets you steepest descent.");
1304 /* ENERGY CONSERVATION */
1305 if (ir_NVE(ir) && ir->cutoff_scheme == ecutsGROUP)
1307 if (!ir_vdw_might_be_zero_at_cutoff(ir) && ir->rvdw > 0 && ir->vdw_modifier == eintmodNONE)
1309 sprintf(warn_buf, "You are using a cut-off for VdW interactions with NVE, for good energy conservation use vdwtype = %s (possibly with DispCorr)",
1310 evdw_names[evdwSHIFT]);
1311 warning_note(wi, warn_buf);
1313 if (!ir_coulomb_might_be_zero_at_cutoff(ir) && ir->rcoulomb > 0)
1315 sprintf(warn_buf, "You are using a cut-off for electrostatics with NVE, for good energy conservation use coulombtype = %s or %s",
1316 eel_names[eelPMESWITCH], eel_names[eelRF_ZERO]);
1317 warning_note(wi, warn_buf);
1321 /* IMPLICIT SOLVENT */
1322 if (ir->coulombtype == eelGB_NOTUSED)
1324 sprintf(warn_buf, "Invalid option %s for coulombtype",
1325 eel_names[ir->coulombtype]);
1326 warning_error(wi, warn_buf);
1329 if (ir->bQMMM)
1331 if (ir->cutoff_scheme != ecutsGROUP)
1333 warning_error(wi, "QMMM is currently only supported with cutoff-scheme=group");
1335 if (!EI_DYNAMICS(ir->eI))
1337 char buf[STRLEN];
1338 sprintf(buf, "QMMM is only supported with dynamics, not with integrator %s", ei_names[ir->eI]);
1339 warning_error(wi, buf);
1343 if (ir->bAdress)
1345 gmx_fatal(FARGS, "AdResS simulations are no longer supported");
1349 /* interpret a number of doubles from a string and put them in an array,
1350 after allocating space for them.
1351 str = the input string
1352 n = the (pre-allocated) number of doubles read
1353 r = the output array of doubles. */
1354 static void parse_n_real(char *str, int *n, real **r, warninp_t wi)
1356 auto values = gmx::splitString(str);
1357 *n = values.size();
1359 snew(*r, *n);
1360 for (int i = 0; i < *n; i++)
1364 (*r)[i] = gmx::fromString<real>(values[i]);
1366 catch (gmx::GromacsException &)
1368 warning_error(wi, "Invalid value " + values[i] + " in string in mdp file. Expected a real number.");
1374 static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi)
1377 int i, j, max_n_lambda, nweights, nfep[efptNR];
1378 t_lambda *fep = ir->fepvals;
1379 t_expanded *expand = ir->expandedvals;
1380 real **count_fep_lambdas;
1381 bool bOneLambda = TRUE;
1383 snew(count_fep_lambdas, efptNR);
1385 /* FEP input processing */
1386 /* first, identify the number of lambda values for each type.
1387 All that are nonzero must have the same number */
1389 for (i = 0; i < efptNR; i++)
1391 parse_n_real(fep_lambda[i], &(nfep[i]), &(count_fep_lambdas[i]), wi);
1394 /* now, determine the number of components. All must be either zero, or equal. */
1396 max_n_lambda = 0;
1397 for (i = 0; i < efptNR; i++)
1399 if (nfep[i] > max_n_lambda)
1401 max_n_lambda = nfep[i]; /* here's a nonzero one. All of them
1402 must have the same number if its not zero.*/
1403 break;
1407 for (i = 0; i < efptNR; i++)
1409 if (nfep[i] == 0)
1411 ir->fepvals->separate_dvdl[i] = FALSE;
1413 else if (nfep[i] == max_n_lambda)
1415 if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute the derivative with
1416 respect to the temperature currently */
1418 ir->fepvals->separate_dvdl[i] = TRUE;
1421 else
1423 gmx_fatal(FARGS, "Number of lambdas (%d) for FEP type %s not equal to number of other types (%d)",
1424 nfep[i], efpt_names[i], max_n_lambda);
1427 /* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
1428 ir->fepvals->separate_dvdl[efptTEMPERATURE] = FALSE;
1430 /* the number of lambdas is the number we've read in, which is either zero
1431 or the same for all */
1432 fep->n_lambda = max_n_lambda;
1434 /* allocate space for the array of lambda values */
1435 snew(fep->all_lambda, efptNR);
1436 /* if init_lambda is defined, we need to set lambda */
1437 if ((fep->init_lambda > 0) && (fep->n_lambda == 0))
1439 ir->fepvals->separate_dvdl[efptFEP] = TRUE;
1441 /* otherwise allocate the space for all of the lambdas, and transfer the data */
1442 for (i = 0; i < efptNR; i++)
1444 snew(fep->all_lambda[i], fep->n_lambda);
1445 if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays
1446 are zero */
1448 for (j = 0; j < fep->n_lambda; j++)
1450 fep->all_lambda[i][j] = static_cast<double>(count_fep_lambdas[i][j]);
1452 sfree(count_fep_lambdas[i]);
1455 sfree(count_fep_lambdas);
1457 /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for internal
1458 bookkeeping -- for now, init_lambda */
1460 if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
1462 for (i = 0; i < fep->n_lambda; i++)
1464 fep->all_lambda[efptFEP][i] = fep->init_lambda;
1468 /* check to see if only a single component lambda is defined, and soft core is defined.
1469 In this case, turn on coulomb soft core */
1471 if (max_n_lambda == 0)
1473 bOneLambda = TRUE;
1475 else
1477 for (i = 0; i < efptNR; i++)
1479 if ((nfep[i] != 0) && (i != efptFEP))
1481 bOneLambda = FALSE;
1485 if ((bOneLambda) && (fep->sc_alpha > 0))
1487 fep->bScCoul = TRUE;
1490 /* Fill in the others with the efptFEP if they are not explicitly
1491 specified (i.e. nfep[i] == 0). This means if fep is not defined,
1492 they are all zero. */
1494 for (i = 0; i < efptNR; i++)
1496 if ((nfep[i] == 0) && (i != efptFEP))
1498 for (j = 0; j < fep->n_lambda; j++)
1500 fep->all_lambda[i][j] = fep->all_lambda[efptFEP][j];
1506 /* make it easier if sc_r_power = 48 by increasing it to the 4th power, to be in the right scale. */
1507 if (fep->sc_r_power == 48)
1509 if (fep->sc_alpha > 0.1)
1511 gmx_fatal(FARGS, "sc_alpha (%f) for sc_r_power = 48 should usually be between 0.001 and 0.004", fep->sc_alpha);
1515 /* now read in the weights */
1516 parse_n_real(weights, &nweights, &(expand->init_lambda_weights), wi);
1517 if (nweights == 0)
1519 snew(expand->init_lambda_weights, fep->n_lambda); /* initialize to zero */
1521 else if (nweights != fep->n_lambda)
1523 gmx_fatal(FARGS, "Number of weights (%d) is not equal to number of lambda values (%d)",
1524 nweights, fep->n_lambda);
1526 if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
1528 expand->nstexpanded = fep->nstdhdl;
1529 /* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
1531 if ((expand->nstexpanded < 0) && ir->bSimTemp)
1533 expand->nstexpanded = 2*static_cast<int>(ir->opts.tau_t[0]/ir->delta_t);
1534 /* if you don't specify nstexpanded when doing expanded ensemble simulated tempering, it is set to
1535 2*tau_t just to be careful so it's not to frequent */
1540 static void do_simtemp_params(t_inputrec *ir)
1543 snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda);
1544 GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]);
1547 static void
1548 convertYesNos(warninp_t /*wi*/, gmx::ArrayRef<const std::string> inputs, const char * /*name*/, gmx_bool *outputs)
1550 int i = 0;
1551 for (const auto &input : inputs)
1553 outputs[i] = (gmx_strncasecmp(input.c_str(), "Y", 1) == 0);
1554 ++i;
1558 template <typename T> void
1559 convertInts(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, T *outputs)
1561 int i = 0;
1562 for (const auto &input : inputs)
1566 outputs[i] = gmx::fromStdString<T>(input);
1568 catch (gmx::GromacsException &)
1570 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of integers separated by spaces.",
1571 name, name);
1572 warning_error(wi, message);
1574 ++i;
1578 static void
1579 convertReals(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, real *outputs)
1581 int i = 0;
1582 for (const auto &input : inputs)
1586 outputs[i] = gmx::fromString<real>(input);
1588 catch (gmx::GromacsException &)
1590 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1591 name, name);
1592 warning_error(wi, message);
1594 ++i;
1598 static void
1599 convertRvecs(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, rvec *outputs)
1601 int i = 0, d = 0;
1602 for (const auto &input : inputs)
1606 outputs[i][d] = gmx::fromString<real>(input);
1608 catch (gmx::GromacsException &)
1610 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1611 name, name);
1612 warning_error(wi, message);
1614 ++d;
1615 if (d == DIM)
1617 d = 0;
1618 ++i;
1623 static void do_wall_params(t_inputrec *ir,
1624 char *wall_atomtype, char *wall_density,
1625 t_gromppopts *opts,
1626 warninp_t wi)
1628 opts->wall_atomtype[0] = nullptr;
1629 opts->wall_atomtype[1] = nullptr;
1631 ir->wall_atomtype[0] = -1;
1632 ir->wall_atomtype[1] = -1;
1633 ir->wall_density[0] = 0;
1634 ir->wall_density[1] = 0;
1636 if (ir->nwall > 0)
1638 auto wallAtomTypes = gmx::splitString(wall_atomtype);
1639 if (wallAtomTypes.size() != size_t(ir->nwall))
1641 gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu",
1642 ir->nwall, wallAtomTypes.size());
1644 for (int i = 0; i < ir->nwall; i++)
1646 opts->wall_atomtype[i] = gmx_strdup(wallAtomTypes[i].c_str());
1649 if (ir->wall_type == ewt93 || ir->wall_type == ewt104)
1651 auto wallDensity = gmx::splitString(wall_density);
1652 if (wallDensity.size() != size_t(ir->nwall))
1654 gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall, wallDensity.size());
1656 convertReals(wi, wallDensity, "wall-density", ir->wall_density);
1657 for (int i = 0; i < ir->nwall; i++)
1659 if (ir->wall_density[i] <= 0)
1661 gmx_fatal(FARGS, "wall-density[%d] = %f\n", i, ir->wall_density[i]);
1668 static void add_wall_energrps(gmx_groups_t *groups, int nwall, t_symtab *symtab)
1670 int i;
1671 t_grps *grps;
1672 char str[STRLEN];
1674 if (nwall > 0)
1676 srenew(groups->grpname, groups->ngrpname+nwall);
1677 grps = &(groups->grps[egcENER]);
1678 srenew(grps->nm_ind, grps->nr+nwall);
1679 for (i = 0; i < nwall; i++)
1681 sprintf(str, "wall%d", i);
1682 groups->grpname[groups->ngrpname] = put_symtab(symtab, str);
1683 grps->nm_ind[grps->nr++] = groups->ngrpname++;
1688 static void read_expandedparams(std::vector<t_inpfile> *inp,
1689 t_expanded *expand, warninp_t wi)
1691 /* read expanded ensemble parameters */
1692 printStringNewline(inp, "expanded ensemble variables");
1693 expand->nstexpanded = get_eint(inp, "nstexpanded", -1, wi);
1694 expand->elamstats = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
1695 expand->elmcmove = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
1696 expand->elmceq = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
1697 expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
1698 expand->equil_samples = get_eint(inp, "weight-equil-number-samples", -1, wi);
1699 expand->equil_steps = get_eint(inp, "weight-equil-number-steps", -1, wi);
1700 expand->equil_wl_delta = get_ereal(inp, "weight-equil-wl-delta", -1, wi);
1701 expand->equil_ratio = get_ereal(inp, "weight-equil-count-ratio", -1, wi);
1702 printStringNewline(inp, "Seed for Monte Carlo in lambda space");
1703 expand->lmc_seed = get_eint(inp, "lmc-seed", -1, wi);
1704 expand->mc_temp = get_ereal(inp, "mc-temperature", -1, wi);
1705 expand->lmc_repeats = get_eint(inp, "lmc-repeats", 1, wi);
1706 expand->gibbsdeltalam = get_eint(inp, "lmc-gibbsdelta", -1, wi);
1707 expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi);
1708 expand->bSymmetrizedTMatrix = (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0);
1709 expand->nstTij = get_eint(inp, "nst-transition-matrix", -1, wi);
1710 expand->minvarmin = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
1711 expand->c_range = get_eint(inp, "weight-c-range", 0, wi); /* default is just C=0 */
1712 expand->wl_scale = get_ereal(inp, "wl-scale", 0.8, wi);
1713 expand->wl_ratio = get_ereal(inp, "wl-ratio", 0.8, wi);
1714 expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi);
1715 expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
1718 /*! \brief Return whether an end state with the given coupling-lambda
1719 * value describes fully-interacting VDW.
1721 * \param[in] couple_lambda_value Enumeration ecouplam value describing the end state
1722 * \return Whether VDW is on (i.e. the user chose vdw or vdw-q in the .mdp file)
1724 static bool couple_lambda_has_vdw_on(int couple_lambda_value)
1726 return (couple_lambda_value == ecouplamVDW ||
1727 couple_lambda_value == ecouplamVDWQ);
1730 namespace
1733 class MdpErrorHandler : public gmx::IKeyValueTreeErrorHandler
1735 public:
1736 explicit MdpErrorHandler(warninp_t wi)
1737 : wi_(wi), mapping_(nullptr)
1741 void setBackMapping(const gmx::IKeyValueTreeBackMapping &mapping)
1743 mapping_ = &mapping;
1746 bool onError(gmx::UserInputError *ex, const gmx::KeyValueTreePath &context) override
1748 ex->prependContext(gmx::formatString("Error in mdp option \"%s\":",
1749 getOptionName(context).c_str()));
1750 std::string message = gmx::formatExceptionMessageToString(*ex);
1751 warning_error(wi_, message.c_str());
1752 return true;
1755 private:
1756 std::string getOptionName(const gmx::KeyValueTreePath &context)
1758 if (mapping_ != nullptr)
1760 gmx::KeyValueTreePath path = mapping_->originalPath(context);
1761 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
1762 return path[0];
1764 GMX_ASSERT(context.size() == 1, "Inconsistent context for mdp option parsing");
1765 return context[0];
1768 warninp_t wi_;
1769 const gmx::IKeyValueTreeBackMapping *mapping_;
1772 } // namespace
1774 void get_ir(const char *mdparin, const char *mdparout,
1775 gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
1776 WriteMdpHeader writeMdpHeader, warninp_t wi)
1778 char *dumstr[2];
1779 double dumdub[2][6];
1780 int i, j, m;
1781 char warn_buf[STRLEN];
1782 t_lambda *fep = ir->fepvals;
1783 t_expanded *expand = ir->expandedvals;
1785 const char *no_names[] = { "no", nullptr };
1787 init_inputrec_strings();
1788 gmx::TextInputFile stream(mdparin);
1789 std::vector<t_inpfile> inp = read_inpfile(&stream, mdparin, wi);
1791 snew(dumstr[0], STRLEN);
1792 snew(dumstr[1], STRLEN);
1794 if (-1 == search_einp(inp, "cutoff-scheme"))
1796 sprintf(warn_buf,
1797 "%s did not specify a value for the .mdp option "
1798 "\"cutoff-scheme\". Probably it was first intended for use "
1799 "with GROMACS before 4.6. In 4.6, the Verlet scheme was "
1800 "introduced, but the group scheme was still the default. "
1801 "The default is now the Verlet scheme, so you will observe "
1802 "different behaviour.", mdparin);
1803 warning_note(wi, warn_buf);
1806 /* ignore the following deprecated commands */
1807 replace_inp_entry(inp, "title", nullptr);
1808 replace_inp_entry(inp, "cpp", nullptr);
1809 replace_inp_entry(inp, "domain-decomposition", nullptr);
1810 replace_inp_entry(inp, "andersen-seed", nullptr);
1811 replace_inp_entry(inp, "dihre", nullptr);
1812 replace_inp_entry(inp, "dihre-fc", nullptr);
1813 replace_inp_entry(inp, "dihre-tau", nullptr);
1814 replace_inp_entry(inp, "nstdihreout", nullptr);
1815 replace_inp_entry(inp, "nstcheckpoint", nullptr);
1816 replace_inp_entry(inp, "optimize-fft", nullptr);
1817 replace_inp_entry(inp, "adress_type", nullptr);
1818 replace_inp_entry(inp, "adress_const_wf", nullptr);
1819 replace_inp_entry(inp, "adress_ex_width", nullptr);
1820 replace_inp_entry(inp, "adress_hy_width", nullptr);
1821 replace_inp_entry(inp, "adress_ex_forcecap", nullptr);
1822 replace_inp_entry(inp, "adress_interface_correction", nullptr);
1823 replace_inp_entry(inp, "adress_site", nullptr);
1824 replace_inp_entry(inp, "adress_reference_coords", nullptr);
1825 replace_inp_entry(inp, "adress_tf_grp_names", nullptr);
1826 replace_inp_entry(inp, "adress_cg_grp_names", nullptr);
1827 replace_inp_entry(inp, "adress_do_hybridpairs", nullptr);
1828 replace_inp_entry(inp, "rlistlong", nullptr);
1829 replace_inp_entry(inp, "nstcalclr", nullptr);
1830 replace_inp_entry(inp, "pull-print-com2", nullptr);
1831 replace_inp_entry(inp, "gb-algorithm", nullptr);
1832 replace_inp_entry(inp, "nstgbradii", nullptr);
1833 replace_inp_entry(inp, "rgbradii", nullptr);
1834 replace_inp_entry(inp, "gb-epsilon-solvent", nullptr);
1835 replace_inp_entry(inp, "gb-saltconc", nullptr);
1836 replace_inp_entry(inp, "gb-obc-alpha", nullptr);
1837 replace_inp_entry(inp, "gb-obc-beta", nullptr);
1838 replace_inp_entry(inp, "gb-obc-gamma", nullptr);
1839 replace_inp_entry(inp, "gb-dielectric-offset", nullptr);
1840 replace_inp_entry(inp, "sa-algorithm", nullptr);
1841 replace_inp_entry(inp, "sa-surface-tension", nullptr);
1843 /* replace the following commands with the clearer new versions*/
1844 replace_inp_entry(inp, "unconstrained-start", "continuation");
1845 replace_inp_entry(inp, "foreign-lambda", "fep-lambdas");
1846 replace_inp_entry(inp, "verlet-buffer-drift", "verlet-buffer-tolerance");
1847 replace_inp_entry(inp, "nstxtcout", "nstxout-compressed");
1848 replace_inp_entry(inp, "xtc-grps", "compressed-x-grps");
1849 replace_inp_entry(inp, "xtc-precision", "compressed-x-precision");
1850 replace_inp_entry(inp, "pull-print-com1", "pull-print-com");
1852 printStringNewline(&inp, "VARIOUS PREPROCESSING OPTIONS");
1853 printStringNoNewline(&inp, "Preprocessor information: use cpp syntax.");
1854 printStringNoNewline(&inp, "e.g.: -I/home/joe/doe -I/home/mary/roe");
1855 setStringEntry(&inp, "include", opts->include, nullptr);
1856 printStringNoNewline(&inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)");
1857 setStringEntry(&inp, "define", opts->define, nullptr);
1859 printStringNewline(&inp, "RUN CONTROL PARAMETERS");
1860 ir->eI = get_eeenum(&inp, "integrator", ei_names, wi);
1861 printStringNoNewline(&inp, "Start time and timestep in ps");
1862 ir->init_t = get_ereal(&inp, "tinit", 0.0, wi);
1863 ir->delta_t = get_ereal(&inp, "dt", 0.001, wi);
1864 ir->nsteps = get_eint64(&inp, "nsteps", 0, wi);
1865 printStringNoNewline(&inp, "For exact run continuation or redoing part of a run");
1866 ir->init_step = get_eint64(&inp, "init-step", 0, wi);
1867 printStringNoNewline(&inp, "Part index is updated automatically on checkpointing (keeps files separate)");
1868 ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
1869 printStringNoNewline(&inp, "mode for center of mass motion removal");
1870 ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi);
1871 printStringNoNewline(&inp, "number of steps for center of mass motion removal");
1872 ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi);
1873 printStringNoNewline(&inp, "group(s) for center of mass motion removal");
1874 setStringEntry(&inp, "comm-grps", is->vcm, nullptr);
1876 printStringNewline(&inp, "LANGEVIN DYNAMICS OPTIONS");
1877 printStringNoNewline(&inp, "Friction coefficient (amu/ps) and random seed");
1878 ir->bd_fric = get_ereal(&inp, "bd-fric", 0.0, wi);
1879 ir->ld_seed = get_eint64(&inp, "ld-seed", -1, wi);
1881 /* Em stuff */
1882 printStringNewline(&inp, "ENERGY MINIMIZATION OPTIONS");
1883 printStringNoNewline(&inp, "Force tolerance and initial step-size");
1884 ir->em_tol = get_ereal(&inp, "emtol", 10.0, wi);
1885 ir->em_stepsize = get_ereal(&inp, "emstep", 0.01, wi);
1886 printStringNoNewline(&inp, "Max number of iterations in relax-shells");
1887 ir->niter = get_eint(&inp, "niter", 20, wi);
1888 printStringNoNewline(&inp, "Step size (ps^2) for minimization of flexible constraints");
1889 ir->fc_stepsize = get_ereal(&inp, "fcstep", 0, wi);
1890 printStringNoNewline(&inp, "Frequency of steepest descents steps when doing CG");
1891 ir->nstcgsteep = get_eint(&inp, "nstcgsteep", 1000, wi);
1892 ir->nbfgscorr = get_eint(&inp, "nbfgscorr", 10, wi);
1894 printStringNewline(&inp, "TEST PARTICLE INSERTION OPTIONS");
1895 ir->rtpi = get_ereal(&inp, "rtpi", 0.05, wi);
1897 /* Output options */
1898 printStringNewline(&inp, "OUTPUT CONTROL OPTIONS");
1899 printStringNoNewline(&inp, "Output frequency for coords (x), velocities (v) and forces (f)");
1900 ir->nstxout = get_eint(&inp, "nstxout", 0, wi);
1901 ir->nstvout = get_eint(&inp, "nstvout", 0, wi);
1902 ir->nstfout = get_eint(&inp, "nstfout", 0, wi);
1903 printStringNoNewline(&inp, "Output frequency for energies to log file and energy file");
1904 ir->nstlog = get_eint(&inp, "nstlog", 1000, wi);
1905 ir->nstcalcenergy = get_eint(&inp, "nstcalcenergy", 100, wi);
1906 ir->nstenergy = get_eint(&inp, "nstenergy", 1000, wi);
1907 printStringNoNewline(&inp, "Output frequency and precision for .xtc file");
1908 ir->nstxout_compressed = get_eint(&inp, "nstxout-compressed", 0, wi);
1909 ir->x_compression_precision = get_ereal(&inp, "compressed-x-precision", 1000.0, wi);
1910 printStringNoNewline(&inp, "This selects the subset of atoms for the compressed");
1911 printStringNoNewline(&inp, "trajectory file. You can select multiple groups. By");
1912 printStringNoNewline(&inp, "default, all atoms will be written.");
1913 setStringEntry(&inp, "compressed-x-grps", is->x_compressed_groups, nullptr);
1914 printStringNoNewline(&inp, "Selection of energy groups");
1915 setStringEntry(&inp, "energygrps", is->energy, nullptr);
1917 /* Neighbor searching */
1918 printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
1919 printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)");
1920 ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi);
1921 printStringNoNewline(&inp, "nblist update frequency");
1922 ir->nstlist = get_eint(&inp, "nstlist", 10, wi);
1923 printStringNoNewline(&inp, "ns algorithm (simple or grid)");
1924 ir->ns_type = get_eeenum(&inp, "ns-type", ens_names, wi);
1925 printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
1926 ir->ePBC = get_eeenum(&inp, "pbc", epbc_names, wi);
1927 ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0;
1928 printStringNoNewline(&inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
1929 printStringNoNewline(&inp, "a value of -1 means: use rlist");
1930 ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance", 0.005, wi);
1931 printStringNoNewline(&inp, "nblist cut-off");
1932 ir->rlist = get_ereal(&inp, "rlist", 1.0, wi);
1933 printStringNoNewline(&inp, "long-range cut-off for switched potentials");
1935 /* Electrostatics */
1936 printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
1937 printStringNoNewline(&inp, "Method for doing electrostatics");
1938 ir->coulombtype = get_eeenum(&inp, "coulombtype", eel_names, wi);
1939 ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi);
1940 printStringNoNewline(&inp, "cut-off lengths");
1941 ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi);
1942 ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi);
1943 printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
1944 ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi);
1945 ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
1946 printStringNoNewline(&inp, "Method for doing Van der Waals");
1947 ir->vdwtype = get_eeenum(&inp, "vdw-type", evdw_names, wi);
1948 ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi);
1949 printStringNoNewline(&inp, "cut-off lengths");
1950 ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi);
1951 ir->rvdw = get_ereal(&inp, "rvdw", 1.0, wi);
1952 printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
1953 ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi);
1954 printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
1955 ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
1956 printStringNoNewline(&inp, "Separate tables between energy group pairs");
1957 setStringEntry(&inp, "energygrp-table", is->egptable, nullptr);
1958 printStringNoNewline(&inp, "Spacing for the PME/PPPM FFT grid");
1959 ir->fourier_spacing = get_ereal(&inp, "fourierspacing", 0.12, wi);
1960 printStringNoNewline(&inp, "FFT grid size, when a value is 0 fourierspacing will be used");
1961 ir->nkx = get_eint(&inp, "fourier-nx", 0, wi);
1962 ir->nky = get_eint(&inp, "fourier-ny", 0, wi);
1963 ir->nkz = get_eint(&inp, "fourier-nz", 0, wi);
1964 printStringNoNewline(&inp, "EWALD/PME/PPPM parameters");
1965 ir->pme_order = get_eint(&inp, "pme-order", 4, wi);
1966 ir->ewald_rtol = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
1967 ir->ewald_rtol_lj = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
1968 ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
1969 ir->ewald_geometry = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
1970 ir->epsilon_surface = get_ereal(&inp, "epsilon-surface", 0.0, wi);
1972 /* Implicit solvation is no longer supported, but we need grompp
1973 to be able to refuse old .mdp files that would have built a tpr
1974 to run it. Thus, only "no" is accepted. */
1975 ir->implicit_solvent = (get_eeenum(&inp, "implicit-solvent", no_names, wi) != 0);
1977 /* Coupling stuff */
1978 printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
1979 printStringNoNewline(&inp, "Temperature coupling");
1980 ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
1981 ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi);
1982 ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
1983 ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
1984 printStringNoNewline(&inp, "Groups to couple separately");
1985 setStringEntry(&inp, "tc-grps", is->tcgrps, nullptr);
1986 printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
1987 setStringEntry(&inp, "tau-t", is->tau_t, nullptr);
1988 setStringEntry(&inp, "ref-t", is->ref_t, nullptr);
1989 printStringNoNewline(&inp, "pressure coupling");
1990 ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
1991 ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
1992 ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
1993 printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
1994 ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi);
1995 setStringEntry(&inp, "compressibility", dumstr[0], nullptr);
1996 setStringEntry(&inp, "ref-p", dumstr[1], nullptr);
1997 printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
1998 ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
2000 /* QMMM */
2001 printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
2002 ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0);
2003 printStringNoNewline(&inp, "Groups treated Quantum Mechanically");
2004 setStringEntry(&inp, "QMMM-grps", is->QMMM, nullptr);
2005 printStringNoNewline(&inp, "QM method");
2006 setStringEntry(&inp, "QMmethod", is->QMmethod, nullptr);
2007 printStringNoNewline(&inp, "QMMM scheme");
2008 ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme", eQMMMscheme_names, wi);
2009 printStringNoNewline(&inp, "QM basisset");
2010 setStringEntry(&inp, "QMbasis", is->QMbasis, nullptr);
2011 printStringNoNewline(&inp, "QM charge");
2012 setStringEntry(&inp, "QMcharge", is->QMcharge, nullptr);
2013 printStringNoNewline(&inp, "QM multiplicity");
2014 setStringEntry(&inp, "QMmult", is->QMmult, nullptr);
2015 printStringNoNewline(&inp, "Surface Hopping");
2016 setStringEntry(&inp, "SH", is->bSH, nullptr);
2017 printStringNoNewline(&inp, "CAS space options");
2018 setStringEntry(&inp, "CASorbitals", is->CASorbitals, nullptr);
2019 setStringEntry(&inp, "CASelectrons", is->CASelectrons, nullptr);
2020 setStringEntry(&inp, "SAon", is->SAon, nullptr);
2021 setStringEntry(&inp, "SAoff", is->SAoff, nullptr);
2022 setStringEntry(&inp, "SAsteps", is->SAsteps, nullptr);
2023 printStringNoNewline(&inp, "Scale factor for MM charges");
2024 ir->scalefactor = get_ereal(&inp, "MMChargeScaleFactor", 1.0, wi);
2026 /* Simulated annealing */
2027 printStringNewline(&inp, "SIMULATED ANNEALING");
2028 printStringNoNewline(&inp, "Type of annealing for each temperature group (no/single/periodic)");
2029 setStringEntry(&inp, "annealing", is->anneal, nullptr);
2030 printStringNoNewline(&inp, "Number of time points to use for specifying annealing in each group");
2031 setStringEntry(&inp, "annealing-npoints", is->anneal_npoints, nullptr);
2032 printStringNoNewline(&inp, "List of times at the annealing points for each group");
2033 setStringEntry(&inp, "annealing-time", is->anneal_time, nullptr);
2034 printStringNoNewline(&inp, "Temp. at each annealing point, for each group.");
2035 setStringEntry(&inp, "annealing-temp", is->anneal_temp, nullptr);
2037 /* Startup run */
2038 printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
2039 opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0);
2040 opts->tempi = get_ereal(&inp, "gen-temp", 300.0, wi);
2041 opts->seed = get_eint(&inp, "gen-seed", -1, wi);
2043 /* Shake stuff */
2044 printStringNewline(&inp, "OPTIONS FOR BONDS");
2045 opts->nshake = get_eeenum(&inp, "constraints", constraints, wi);
2046 printStringNoNewline(&inp, "Type of constraint algorithm");
2047 ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
2048 printStringNoNewline(&inp, "Do not constrain the start configuration");
2049 ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0);
2050 printStringNoNewline(&inp, "Use successive overrelaxation to reduce the number of shake iterations");
2051 ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0);
2052 printStringNoNewline(&inp, "Relative tolerance of shake");
2053 ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
2054 printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
2055 ir->nProjOrder = get_eint(&inp, "lincs-order", 4, wi);
2056 printStringNoNewline(&inp, "Number of iterations in the final step of LINCS. 1 is fine for");
2057 printStringNoNewline(&inp, "normal simulations, but use 2 to conserve energy in NVE runs.");
2058 printStringNoNewline(&inp, "For energy minimization with constraints it should be 4 to 8.");
2059 ir->nLincsIter = get_eint(&inp, "lincs-iter", 1, wi);
2060 printStringNoNewline(&inp, "Lincs will write a warning to the stderr if in one step a bond");
2061 printStringNoNewline(&inp, "rotates over more degrees than");
2062 ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
2063 printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
2064 opts->bMorse = (get_eeenum(&inp, "morse", yesno_names, wi) != 0);
2066 /* Energy group exclusions */
2067 printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
2068 printStringNoNewline(&inp, "Pairs of energy groups for which all non-bonded interactions are excluded");
2069 setStringEntry(&inp, "energygrp-excl", is->egpexcl, nullptr);
2071 /* Walls */
2072 printStringNewline(&inp, "WALLS");
2073 printStringNoNewline(&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
2074 ir->nwall = get_eint(&inp, "nwall", 0, wi);
2075 ir->wall_type = get_eeenum(&inp, "wall-type", ewt_names, wi);
2076 ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
2077 setStringEntry(&inp, "wall-atomtype", is->wall_atomtype, nullptr);
2078 setStringEntry(&inp, "wall-density", is->wall_density, nullptr);
2079 ir->wall_ewald_zfac = get_ereal(&inp, "wall-ewald-zfac", 3, wi);
2081 /* COM pulling */
2082 printStringNewline(&inp, "COM PULLING");
2083 ir->bPull = (get_eeenum(&inp, "pull", yesno_names, wi) != 0);
2084 if (ir->bPull)
2086 snew(ir->pull, 1);
2087 is->pull_grp = read_pullparams(&inp, ir->pull, wi);
2090 /* AWH biasing
2091 NOTE: needs COM pulling input */
2092 printStringNewline(&inp, "AWH biasing");
2093 ir->bDoAwh = (get_eeenum(&inp, "awh", yesno_names, wi) != 0);
2094 if (ir->bDoAwh)
2096 if (ir->bPull)
2098 ir->awhParams = gmx::readAndCheckAwhParams(&inp, ir, wi);
2100 else
2102 gmx_fatal(FARGS, "AWH biasing is only compatible with COM pulling turned on");
2106 /* Enforced rotation */
2107 printStringNewline(&inp, "ENFORCED ROTATION");
2108 printStringNoNewline(&inp, "Enforced rotation: No or Yes");
2109 ir->bRot = (get_eeenum(&inp, "rotation", yesno_names, wi) != 0);
2110 if (ir->bRot)
2112 snew(ir->rot, 1);
2113 is->rot_grp = read_rotparams(&inp, ir->rot, wi);
2116 /* Interactive MD */
2117 ir->bIMD = FALSE;
2118 printStringNewline(&inp, "Group to display and/or manipulate in interactive MD session");
2119 setStringEntry(&inp, "IMD-group", is->imd_grp, nullptr);
2120 if (is->imd_grp[0] != '\0')
2122 snew(ir->imd, 1);
2123 ir->bIMD = TRUE;
2126 /* Refinement */
2127 printStringNewline(&inp, "NMR refinement stuff");
2128 printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
2129 ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi);
2130 printStringNoNewline(&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
2131 ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
2132 printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
2133 ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0);
2134 ir->dr_fc = get_ereal(&inp, "disre-fc", 1000.0, wi);
2135 ir->dr_tau = get_ereal(&inp, "disre-tau", 0.0, wi);
2136 printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
2137 ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
2138 printStringNoNewline(&inp, "Orientation restraints: No or Yes");
2139 opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0);
2140 printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
2141 ir->orires_fc = get_ereal(&inp, "orire-fc", 0.0, wi);
2142 ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
2143 setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp, nullptr);
2144 printStringNoNewline(&inp, "Output frequency for trace(SD) and S to energy file");
2145 ir->nstorireout = get_eint(&inp, "nstorireout", 100, wi);
2147 /* free energy variables */
2148 printStringNewline(&inp, "Free energy variables");
2149 ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
2150 setStringEntry(&inp, "couple-moltype", is->couple_moltype, nullptr);
2151 opts->couple_lam0 = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
2152 opts->couple_lam1 = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
2153 opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0);
2155 fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
2156 we can recognize if
2157 it was not entered */
2158 fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
2159 fep->delta_lambda = get_ereal(&inp, "delta-lambda", 0.0, wi);
2160 fep->nstdhdl = get_eint(&inp, "nstdhdl", 50, wi);
2161 setStringEntry(&inp, "fep-lambdas", is->fep_lambda[efptFEP], nullptr);
2162 setStringEntry(&inp, "mass-lambdas", is->fep_lambda[efptMASS], nullptr);
2163 setStringEntry(&inp, "coul-lambdas", is->fep_lambda[efptCOUL], nullptr);
2164 setStringEntry(&inp, "vdw-lambdas", is->fep_lambda[efptVDW], nullptr);
2165 setStringEntry(&inp, "bonded-lambdas", is->fep_lambda[efptBONDED], nullptr);
2166 setStringEntry(&inp, "restraint-lambdas", is->fep_lambda[efptRESTRAINT], nullptr);
2167 setStringEntry(&inp, "temperature-lambdas", is->fep_lambda[efptTEMPERATURE], nullptr);
2168 fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
2169 setStringEntry(&inp, "init-lambda-weights", is->lambda_weights, nullptr);
2170 fep->edHdLPrintEnergy = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
2171 fep->sc_alpha = get_ereal(&inp, "sc-alpha", 0.0, wi);
2172 fep->sc_power = get_eint(&inp, "sc-power", 1, wi);
2173 fep->sc_r_power = get_ereal(&inp, "sc-r-power", 6.0, wi);
2174 fep->sc_sigma = get_ereal(&inp, "sc-sigma", 0.3, wi);
2175 fep->bScCoul = (get_eeenum(&inp, "sc-coul", yesno_names, wi) != 0);
2176 fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
2177 fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2178 fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
2179 fep->dhdl_derivatives = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
2180 fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
2181 fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2183 /* Non-equilibrium MD stuff */
2184 printStringNewline(&inp, "Non-equilibrium MD stuff");
2185 setStringEntry(&inp, "acc-grps", is->accgrps, nullptr);
2186 setStringEntry(&inp, "accelerate", is->acc, nullptr);
2187 setStringEntry(&inp, "freezegrps", is->freeze, nullptr);
2188 setStringEntry(&inp, "freezedim", is->frdim, nullptr);
2189 ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
2190 setStringEntry(&inp, "deform", is->deform, nullptr);
2192 /* simulated tempering variables */
2193 printStringNewline(&inp, "simulated tempering variables");
2194 ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0);
2195 ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
2196 ir->simtempvals->simtemp_low = get_ereal(&inp, "sim-temp-low", 300.0, wi);
2197 ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi);
2199 /* expanded ensemble variables */
2200 if (ir->efep == efepEXPANDED || ir->bSimTemp)
2202 read_expandedparams(&inp, expand, wi);
2205 /* Electric fields */
2207 gmx::KeyValueTreeObject convertedValues = flatKeyValueTreeFromInpFile(inp);
2208 gmx::KeyValueTreeTransformer transform;
2209 transform.rules()->addRule()
2210 .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
2211 mdModules->initMdpTransform(transform.rules());
2212 for (const auto &path : transform.mappedPaths())
2214 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
2215 mark_einp_set(inp, path[0].c_str());
2217 MdpErrorHandler errorHandler(wi);
2218 auto result
2219 = transform.transform(convertedValues, &errorHandler);
2220 ir->params = new gmx::KeyValueTreeObject(result.object());
2221 mdModules->adjustInputrecBasedOnModules(ir);
2222 errorHandler.setBackMapping(result.backMapping());
2223 mdModules->assignOptionsToModules(*ir->params, &errorHandler);
2226 /* Ion/water position swapping ("computational electrophysiology") */
2227 printStringNewline(&inp, "Ion/water position swapping for computational electrophysiology setups");
2228 printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
2229 ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
2230 if (ir->eSwapCoords != eswapNO)
2232 char buf[STRLEN];
2233 int nIonTypes;
2236 snew(ir->swap, 1);
2237 printStringNoNewline(&inp, "Swap attempt frequency");
2238 ir->swap->nstswap = get_eint(&inp, "swap-frequency", 1, wi);
2239 printStringNoNewline(&inp, "Number of ion types to be controlled");
2240 nIonTypes = get_eint(&inp, "iontypes", 1, wi);
2241 if (nIonTypes < 1)
2243 warning_error(wi, "You need to provide at least one ion type for position exchanges.");
2245 ir->swap->ngrp = nIonTypes + eSwapFixedGrpNR;
2246 snew(ir->swap->grp, ir->swap->ngrp);
2247 for (i = 0; i < ir->swap->ngrp; i++)
2249 snew(ir->swap->grp[i].molname, STRLEN);
2251 printStringNoNewline(&inp, "Two index groups that contain the compartment-partitioning atoms");
2252 setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
2253 setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
2254 printStringNoNewline(&inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used");
2255 ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0);
2256 ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0);
2258 printStringNoNewline(&inp, "Name of solvent molecules");
2259 setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
2261 printStringNoNewline(&inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)");
2262 printStringNoNewline(&inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,");
2263 printStringNoNewline(&inp, "however, if correctly defined, the permeation events are recorded per channel");
2264 ir->swap->cyl0r = get_ereal(&inp, "cyl0-r", 2.0, wi);
2265 ir->swap->cyl0u = get_ereal(&inp, "cyl0-up", 1.0, wi);
2266 ir->swap->cyl0l = get_ereal(&inp, "cyl0-down", 1.0, wi);
2267 ir->swap->cyl1r = get_ereal(&inp, "cyl1-r", 2.0, wi);
2268 ir->swap->cyl1u = get_ereal(&inp, "cyl1-up", 1.0, wi);
2269 ir->swap->cyl1l = get_ereal(&inp, "cyl1-down", 1.0, wi);
2271 printStringNoNewline(&inp, "Average the number of ions per compartment over these many swap attempt steps");
2272 ir->swap->nAverage = get_eint(&inp, "coupl-steps", 10, wi);
2274 printStringNoNewline(&inp, "Names of the ion types that can be exchanged with solvent molecules,");
2275 printStringNoNewline(&inp, "and the requested number of ions of this type in compartments A and B");
2276 printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
2277 for (i = 0; i < nIonTypes; i++)
2279 int ig = eSwapFixedGrpNR + i;
2281 sprintf(buf, "iontype%d-name", i);
2282 setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
2283 sprintf(buf, "iontype%d-in-A", i);
2284 ir->swap->grp[ig].nmolReq[0] = get_eint(&inp, buf, -1, wi);
2285 sprintf(buf, "iontype%d-in-B", i);
2286 ir->swap->grp[ig].nmolReq[1] = get_eint(&inp, buf, -1, wi);
2289 printStringNoNewline(&inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
2290 printStringNoNewline(&inp, "at maximum distance (= bulk concentration) to the split group layers. However,");
2291 printStringNoNewline(&inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
2292 printStringNoNewline(&inp, "towards one of the compartment-partitioning layers (at +/- 1.0).");
2293 ir->swap->bulkOffset[0] = get_ereal(&inp, "bulk-offsetA", 0.0, wi);
2294 ir->swap->bulkOffset[1] = get_ereal(&inp, "bulk-offsetB", 0.0, wi);
2295 if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0)
2296 || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) )
2298 warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !");
2301 printStringNoNewline(&inp, "Start to swap ions if threshold difference to requested count is reached");
2302 ir->swap->threshold = get_ereal(&inp, "threshold", 1.0, wi);
2305 /* AdResS is no longer supported, but we need grompp to be able to
2306 refuse to process old .mdp files that used it. */
2307 ir->bAdress = (get_eeenum(&inp, "adress", no_names, wi) != 0);
2309 /* User defined thingies */
2310 printStringNewline(&inp, "User defined thingies");
2311 setStringEntry(&inp, "user1-grps", is->user1, nullptr);
2312 setStringEntry(&inp, "user2-grps", is->user2, nullptr);
2313 ir->userint1 = get_eint(&inp, "userint1", 0, wi);
2314 ir->userint2 = get_eint(&inp, "userint2", 0, wi);
2315 ir->userint3 = get_eint(&inp, "userint3", 0, wi);
2316 ir->userint4 = get_eint(&inp, "userint4", 0, wi);
2317 ir->userreal1 = get_ereal(&inp, "userreal1", 0, wi);
2318 ir->userreal2 = get_ereal(&inp, "userreal2", 0, wi);
2319 ir->userreal3 = get_ereal(&inp, "userreal3", 0, wi);
2320 ir->userreal4 = get_ereal(&inp, "userreal4", 0, wi);
2321 #undef CTYPE
2324 gmx::TextOutputFile stream(mdparout);
2325 write_inpfile(&stream, mdparout, &inp, FALSE, writeMdpHeader, wi);
2327 // Transform module data into a flat key-value tree for output.
2328 gmx::KeyValueTreeBuilder builder;
2329 gmx::KeyValueTreeObjectBuilder builderObject = builder.rootObject();
2330 mdModules->buildMdpOutput(&builderObject);
2332 gmx::TextWriter writer(&stream);
2333 writeKeyValueTreeAsMdp(&writer, builder.build());
2335 stream.close();
2338 /* Process options if necessary */
2339 for (m = 0; m < 2; m++)
2341 for (i = 0; i < 2*DIM; i++)
2343 dumdub[m][i] = 0.0;
2345 if (ir->epc)
2347 switch (ir->epct)
2349 case epctISOTROPIC:
2350 if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1)
2352 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 1)");
2354 dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX];
2355 break;
2356 case epctSEMIISOTROPIC:
2357 case epctSURFACETENSION:
2358 if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2)
2360 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 2)");
2362 dumdub[m][YY] = dumdub[m][XX];
2363 break;
2364 case epctANISOTROPIC:
2365 if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf",
2366 &(dumdub[m][XX]), &(dumdub[m][YY]), &(dumdub[m][ZZ]),
2367 &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5])) != 6)
2369 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 6)");
2371 break;
2372 default:
2373 gmx_fatal(FARGS, "Pressure coupling type %s not implemented yet",
2374 epcoupltype_names[ir->epct]);
2378 clear_mat(ir->ref_p);
2379 clear_mat(ir->compress);
2380 for (i = 0; i < DIM; i++)
2382 ir->ref_p[i][i] = dumdub[1][i];
2383 ir->compress[i][i] = dumdub[0][i];
2385 if (ir->epct == epctANISOTROPIC)
2387 ir->ref_p[XX][YY] = dumdub[1][3];
2388 ir->ref_p[XX][ZZ] = dumdub[1][4];
2389 ir->ref_p[YY][ZZ] = dumdub[1][5];
2390 if (ir->ref_p[XX][YY] != 0 && ir->ref_p[XX][ZZ] != 0 && ir->ref_p[YY][ZZ] != 0)
2392 warning(wi, "All off-diagonal reference pressures are non-zero. Are you sure you want to apply a threefold shear stress?\n");
2394 ir->compress[XX][YY] = dumdub[0][3];
2395 ir->compress[XX][ZZ] = dumdub[0][4];
2396 ir->compress[YY][ZZ] = dumdub[0][5];
2397 for (i = 0; i < DIM; i++)
2399 for (m = 0; m < i; m++)
2401 ir->ref_p[i][m] = ir->ref_p[m][i];
2402 ir->compress[i][m] = ir->compress[m][i];
2407 if (ir->comm_mode == ecmNO)
2409 ir->nstcomm = 0;
2412 opts->couple_moltype = nullptr;
2413 if (strlen(is->couple_moltype) > 0)
2415 if (ir->efep != efepNO)
2417 opts->couple_moltype = gmx_strdup(is->couple_moltype);
2418 if (opts->couple_lam0 == opts->couple_lam1)
2420 warning(wi, "The lambda=0 and lambda=1 states for coupling are identical");
2422 if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE ||
2423 opts->couple_lam1 == ecouplamNONE))
2425 warning(wi, "For proper sampling of the (nearly) decoupled state, stochastic dynamics should be used");
2428 else
2430 warning_note(wi, "Free energy is turned off, so we will not decouple the molecule listed in your input.");
2433 /* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */
2434 if (ir->efep != efepNO)
2436 if (fep->delta_lambda > 0)
2438 ir->efep = efepSLOWGROWTH;
2442 if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES)
2444 fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2445 warning_note(wi, "Old option for dhdl-print-energy given: "
2446 "changing \"yes\" to \"total\"\n");
2449 if (ir->bSimTemp && (fep->edHdLPrintEnergy == edHdLPrintEnergyNO))
2451 /* always print out the energy to dhdl if we are doing
2452 expanded ensemble, since we need the total energy for
2453 analysis if the temperature is changing. In some
2454 conditions one may only want the potential energy, so
2455 we will allow that if the appropriate mdp setting has
2456 been enabled. Otherwise, total it is:
2458 fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2461 if ((ir->efep != efepNO) || ir->bSimTemp)
2463 ir->bExpanded = FALSE;
2464 if ((ir->efep == efepEXPANDED) || ir->bSimTemp)
2466 ir->bExpanded = TRUE;
2468 do_fep_params(ir, is->fep_lambda, is->lambda_weights, wi);
2469 if (ir->bSimTemp) /* done after fep params */
2471 do_simtemp_params(ir);
2474 /* Because sc-coul (=FALSE by default) only acts on the lambda state
2475 * setup and not on the old way of specifying the free-energy setup,
2476 * we should check for using soft-core when not needed, since that
2477 * can complicate the sampling significantly.
2478 * Note that we only check for the automated coupling setup.
2479 * If the (advanced) user does FEP through manual topology changes,
2480 * this check will not be triggered.
2482 if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 &&
2483 ir->fepvals->sc_alpha != 0 &&
2484 (couple_lambda_has_vdw_on(opts->couple_lam0) &&
2485 couple_lambda_has_vdw_on(opts->couple_lam1)))
2487 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.");
2490 else
2492 ir->fepvals->n_lambda = 0;
2495 /* WALL PARAMETERS */
2497 do_wall_params(ir, is->wall_atomtype, is->wall_density, opts, wi);
2499 /* ORIENTATION RESTRAINT PARAMETERS */
2501 if (opts->bOrire && gmx::splitString(is->orirefitgrp).size() != 1)
2503 warning_error(wi, "ERROR: Need one orientation restraint fit group\n");
2506 /* DEFORMATION PARAMETERS */
2508 clear_mat(ir->deform);
2509 for (i = 0; i < 6; i++)
2511 dumdub[0][i] = 0;
2514 double gmx_unused canary;
2515 int ndeform = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf %lf",
2516 &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]),
2517 &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]), &canary);
2519 if (strlen(is->deform) > 0 && ndeform != 6)
2521 warning_error(wi, gmx::formatString("Cannot parse exactly 6 box deformation velocities from string '%s'", is->deform).c_str());
2523 for (i = 0; i < 3; i++)
2525 ir->deform[i][i] = dumdub[0][i];
2527 ir->deform[YY][XX] = dumdub[0][3];
2528 ir->deform[ZZ][XX] = dumdub[0][4];
2529 ir->deform[ZZ][YY] = dumdub[0][5];
2530 if (ir->epc != epcNO)
2532 for (i = 0; i < 3; i++)
2534 for (j = 0; j <= i; j++)
2536 if (ir->deform[i][j] != 0 && ir->compress[i][j] != 0)
2538 warning_error(wi, "A box element has deform set and compressibility > 0");
2542 for (i = 0; i < 3; i++)
2544 for (j = 0; j < i; j++)
2546 if (ir->deform[i][j] != 0)
2548 for (m = j; m < DIM; m++)
2550 if (ir->compress[m][j] != 0)
2552 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.");
2553 warning(wi, warn_buf);
2561 /* Ion/water position swapping checks */
2562 if (ir->eSwapCoords != eswapNO)
2564 if (ir->swap->nstswap < 1)
2566 warning_error(wi, "swap_frequency must be 1 or larger when ion swapping is requested");
2568 if (ir->swap->nAverage < 1)
2570 warning_error(wi, "coupl_steps must be 1 or larger.\n");
2572 if (ir->swap->threshold < 1.0)
2574 warning_error(wi, "Ion count threshold must be at least 1.\n");
2578 sfree(dumstr[0]);
2579 sfree(dumstr[1]);
2582 static int search_QMstring(const char *s, int ng, const char *gn[])
2584 /* same as normal search_string, but this one searches QM strings */
2585 int i;
2587 for (i = 0; (i < ng); i++)
2589 if (gmx_strcasecmp(s, gn[i]) == 0)
2591 return i;
2595 gmx_fatal(FARGS, "this QM method or basisset (%s) is not implemented\n!", s);
2596 } /* search_QMstring */
2598 /* We would like gn to be const as well, but C doesn't allow this */
2599 /* TODO this is utility functionality (search for the index of a
2600 string in a collection), so should be refactored and located more
2601 centrally. */
2602 int search_string(const char *s, int ng, char *gn[])
2604 int i;
2606 for (i = 0; (i < ng); i++)
2608 if (gmx_strcasecmp(s, gn[i]) == 0)
2610 return i;
2614 gmx_fatal(FARGS,
2615 "Group %s referenced in the .mdp file was not found in the index file.\n"
2616 "Group names must match either [moleculetype] names or custom index group\n"
2617 "names, in which case you must supply an index file to the '-n' option\n"
2618 "of grompp.",
2622 static bool do_numbering(int natoms, gmx_groups_t *groups,
2623 gmx::ArrayRef<std::string> groupsFromMdpFile,
2624 t_blocka *block, char *gnames[],
2625 int gtype, int restnm,
2626 int grptp, bool bVerbose,
2627 warninp_t wi)
2629 unsigned short *cbuf;
2630 t_grps *grps = &(groups->grps[gtype]);
2631 int j, gid, aj, ognr, ntot = 0;
2632 const char *title;
2633 bool bRest;
2634 char warn_buf[STRLEN];
2636 title = gtypes[gtype];
2638 snew(cbuf, natoms);
2639 /* Mark all id's as not set */
2640 for (int i = 0; (i < natoms); i++)
2642 cbuf[i] = NOGID;
2645 snew(grps->nm_ind, groupsFromMdpFile.size()+1); /* +1 for possible rest group */
2646 for (int i = 0; i != groupsFromMdpFile.size(); ++i)
2648 /* Lookup the group name in the block structure */
2649 gid = search_string(groupsFromMdpFile[i].c_str(), block->nr, gnames);
2650 if ((grptp != egrptpONE) || (i == 0))
2652 grps->nm_ind[grps->nr++] = gid;
2655 /* Now go over the atoms in the group */
2656 for (j = block->index[gid]; (j < block->index[gid+1]); j++)
2659 aj = block->a[j];
2661 /* Range checking */
2662 if ((aj < 0) || (aj >= natoms))
2664 gmx_fatal(FARGS, "Invalid atom number %d in indexfile", aj);
2666 /* Lookup up the old group number */
2667 ognr = cbuf[aj];
2668 if (ognr != NOGID)
2670 gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)",
2671 aj+1, title, ognr+1, i+1);
2673 else
2675 /* Store the group number in buffer */
2676 if (grptp == egrptpONE)
2678 cbuf[aj] = 0;
2680 else
2682 cbuf[aj] = i;
2684 ntot++;
2689 /* Now check whether we have done all atoms */
2690 bRest = FALSE;
2691 if (ntot != natoms)
2693 if (grptp == egrptpALL)
2695 gmx_fatal(FARGS, "%d atoms are not part of any of the %s groups",
2696 natoms-ntot, title);
2698 else if (grptp == egrptpPART)
2700 sprintf(warn_buf, "%d atoms are not part of any of the %s groups",
2701 natoms-ntot, title);
2702 warning_note(wi, warn_buf);
2704 /* Assign all atoms currently unassigned to a rest group */
2705 for (j = 0; (j < natoms); j++)
2707 if (cbuf[j] == NOGID)
2709 cbuf[j] = grps->nr;
2710 bRest = TRUE;
2713 if (grptp != egrptpPART)
2715 if (bVerbose)
2717 fprintf(stderr,
2718 "Making dummy/rest group for %s containing %d elements\n",
2719 title, natoms-ntot);
2721 /* Add group name "rest" */
2722 grps->nm_ind[grps->nr] = restnm;
2724 /* Assign the rest name to all atoms not currently assigned to a group */
2725 for (j = 0; (j < natoms); j++)
2727 if (cbuf[j] == NOGID)
2729 cbuf[j] = grps->nr;
2732 grps->nr++;
2736 if (grps->nr == 1 && (ntot == 0 || ntot == natoms))
2738 /* All atoms are part of one (or no) group, no index required */
2739 groups->ngrpnr[gtype] = 0;
2740 groups->grpnr[gtype] = nullptr;
2742 else
2744 groups->ngrpnr[gtype] = natoms;
2745 snew(groups->grpnr[gtype], natoms);
2746 for (j = 0; (j < natoms); j++)
2748 groups->grpnr[gtype][j] = cbuf[j];
2752 sfree(cbuf);
2754 return (bRest && grptp == egrptpPART);
2757 static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
2759 t_grpopts *opts;
2760 const gmx_groups_t *groups;
2761 pull_params_t *pull;
2762 int natoms, ai, aj, i, j, d, g, imin, jmin;
2763 int *nrdf2, *na_vcm, na_tot;
2764 double *nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub;
2765 ivec *dof_vcm;
2766 gmx_mtop_atomloop_all_t aloop;
2767 int mol, ftype, as;
2769 /* Calculate nrdf.
2770 * First calc 3xnr-atoms for each group
2771 * then subtract half a degree of freedom for each constraint
2773 * Only atoms and nuclei contribute to the degrees of freedom...
2776 opts = &ir->opts;
2778 groups = &mtop->groups;
2779 natoms = mtop->natoms;
2781 /* Allocate one more for a possible rest group */
2782 /* We need to sum degrees of freedom into doubles,
2783 * since floats give too low nrdf's above 3 million atoms.
2785 snew(nrdf_tc, groups->grps[egcTC].nr+1);
2786 snew(nrdf_vcm, groups->grps[egcVCM].nr+1);
2787 snew(dof_vcm, groups->grps[egcVCM].nr+1);
2788 snew(na_vcm, groups->grps[egcVCM].nr+1);
2789 snew(nrdf_vcm_sub, groups->grps[egcVCM].nr+1);
2791 for (i = 0; i < groups->grps[egcTC].nr; i++)
2793 nrdf_tc[i] = 0;
2795 for (i = 0; i < groups->grps[egcVCM].nr+1; i++)
2797 nrdf_vcm[i] = 0;
2798 clear_ivec(dof_vcm[i]);
2799 na_vcm[i] = 0;
2800 nrdf_vcm_sub[i] = 0;
2803 snew(nrdf2, natoms);
2804 aloop = gmx_mtop_atomloop_all_init(mtop);
2805 const t_atom *atom;
2806 while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
2808 nrdf2[i] = 0;
2809 if (atom->ptype == eptAtom || atom->ptype == eptNucleus)
2811 g = getGroupType(groups, egcFREEZE, i);
2812 for (d = 0; d < DIM; d++)
2814 if (opts->nFreeze[g][d] == 0)
2816 /* Add one DOF for particle i (counted as 2*1) */
2817 nrdf2[i] += 2;
2818 /* VCM group i has dim d as a DOF */
2819 dof_vcm[getGroupType(groups, egcVCM, i)][d] = 1;
2822 nrdf_tc [getGroupType(groups, egcTC, i)] += 0.5*nrdf2[i];
2823 nrdf_vcm[getGroupType(groups, egcVCM, i)] += 0.5*nrdf2[i];
2827 as = 0;
2828 for (const gmx_molblock_t &molb : mtop->molblock)
2830 const gmx_moltype_t &molt = mtop->moltype[molb.type];
2831 atom = molt.atoms.atom;
2832 for (mol = 0; mol < molb.nmol; mol++)
2834 for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
2836 gmx::ArrayRef<const int> ia = molt.ilist[ftype].iatoms;
2837 for (i = 0; i < molt.ilist[ftype].size(); )
2839 /* Subtract degrees of freedom for the constraints,
2840 * if the particles still have degrees of freedom left.
2841 * If one of the particles is a vsite or a shell, then all
2842 * constraint motion will go there, but since they do not
2843 * contribute to the constraints the degrees of freedom do not
2844 * change.
2846 ai = as + ia[i + 1];
2847 aj = as + ia[i + 2];
2848 if (((atom[ia[i + 1]].ptype == eptNucleus) ||
2849 (atom[ia[i + 1]].ptype == eptAtom)) &&
2850 ((atom[ia[i + 2]].ptype == eptNucleus) ||
2851 (atom[ia[i + 2]].ptype == eptAtom)))
2853 if (nrdf2[ai] > 0)
2855 jmin = 1;
2857 else
2859 jmin = 2;
2861 if (nrdf2[aj] > 0)
2863 imin = 1;
2865 else
2867 imin = 2;
2869 imin = std::min(imin, nrdf2[ai]);
2870 jmin = std::min(jmin, nrdf2[aj]);
2871 nrdf2[ai] -= imin;
2872 nrdf2[aj] -= jmin;
2873 nrdf_tc [getGroupType(groups, egcTC, ai)] -= 0.5*imin;
2874 nrdf_tc [getGroupType(groups, egcTC, aj)] -= 0.5*jmin;
2875 nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
2876 nrdf_vcm[getGroupType(groups, egcVCM, aj)] -= 0.5*jmin;
2878 i += interaction_function[ftype].nratoms+1;
2881 gmx::ArrayRef<const int> ia = molt.ilist[F_SETTLE].iatoms;
2882 for (i = 0; i < molt.ilist[F_SETTLE].size(); )
2884 /* Subtract 1 dof from every atom in the SETTLE */
2885 for (j = 0; j < 3; j++)
2887 ai = as + ia[i + 1 + j];
2888 imin = std::min(2, nrdf2[ai]);
2889 nrdf2[ai] -= imin;
2890 nrdf_tc [getGroupType(groups, egcTC, ai)] -= 0.5*imin;
2891 nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
2893 i += 4;
2895 as += molt.atoms.nr;
2899 if (ir->bPull)
2901 /* Correct nrdf for the COM constraints.
2902 * We correct using the TC and VCM group of the first atom
2903 * in the reference and pull group. If atoms in one pull group
2904 * belong to different TC or VCM groups it is anyhow difficult
2905 * to determine the optimal nrdf assignment.
2907 pull = ir->pull;
2909 for (i = 0; i < pull->ncoord; i++)
2911 if (pull->coord[i].eType != epullCONSTRAINT)
2913 continue;
2916 imin = 1;
2918 for (j = 0; j < 2; j++)
2920 const t_pull_group *pgrp;
2922 pgrp = &pull->group[pull->coord[i].group[j]];
2924 if (pgrp->nat > 0)
2926 /* Subtract 1/2 dof from each group */
2927 ai = pgrp->ind[0];
2928 nrdf_tc [getGroupType(groups, egcTC, ai)] -= 0.5*imin;
2929 nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
2930 if (nrdf_tc[getGroupType(groups, egcTC, ai)] < 0)
2932 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)]]);
2935 else
2937 /* We need to subtract the whole DOF from group j=1 */
2938 imin += 1;
2944 if (ir->nstcomm != 0)
2946 int ndim_rm_vcm;
2948 /* We remove COM motion up to dim ndof_com() */
2949 ndim_rm_vcm = ndof_com(ir);
2951 /* Subtract ndim_rm_vcm (or less with frozen dimensions) from
2952 * the number of degrees of freedom in each vcm group when COM
2953 * translation is removed and 6 when rotation is removed as well.
2955 for (j = 0; j < groups->grps[egcVCM].nr+1; j++)
2957 switch (ir->comm_mode)
2959 case ecmLINEAR:
2960 case ecmLINEAR_ACCELERATION_CORRECTION:
2961 nrdf_vcm_sub[j] = 0;
2962 for (d = 0; d < ndim_rm_vcm; d++)
2964 if (dof_vcm[j][d])
2966 nrdf_vcm_sub[j]++;
2969 break;
2970 case ecmANGULAR:
2971 nrdf_vcm_sub[j] = 6;
2972 break;
2973 default:
2974 gmx_incons("Checking comm_mode");
2978 for (i = 0; i < groups->grps[egcTC].nr; i++)
2980 /* Count the number of atoms of TC group i for every VCM group */
2981 for (j = 0; j < groups->grps[egcVCM].nr+1; j++)
2983 na_vcm[j] = 0;
2985 na_tot = 0;
2986 for (ai = 0; ai < natoms; ai++)
2988 if (getGroupType(groups, egcTC, ai) == i)
2990 na_vcm[getGroupType(groups, egcVCM, ai)]++;
2991 na_tot++;
2994 /* Correct for VCM removal according to the fraction of each VCM
2995 * group present in this TC group.
2997 nrdf_uc = nrdf_tc[i];
2998 nrdf_tc[i] = 0;
2999 for (j = 0; j < groups->grps[egcVCM].nr+1; j++)
3001 if (nrdf_vcm[j] > nrdf_vcm_sub[j])
3003 nrdf_tc[i] += nrdf_uc*(static_cast<double>(na_vcm[j])/static_cast<double>(na_tot))*
3004 (nrdf_vcm[j] - nrdf_vcm_sub[j])/nrdf_vcm[j];
3009 for (i = 0; (i < groups->grps[egcTC].nr); i++)
3011 opts->nrdf[i] = nrdf_tc[i];
3012 if (opts->nrdf[i] < 0)
3014 opts->nrdf[i] = 0;
3016 fprintf(stderr,
3017 "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
3018 gnames[groups->grps[egcTC].nm_ind[i]], opts->nrdf[i]);
3021 sfree(nrdf2);
3022 sfree(nrdf_tc);
3023 sfree(nrdf_vcm);
3024 sfree(dof_vcm);
3025 sfree(na_vcm);
3026 sfree(nrdf_vcm_sub);
3029 static bool do_egp_flag(t_inputrec *ir, gmx_groups_t *groups,
3030 const char *option, const char *val, int flag)
3032 /* The maximum number of energy group pairs would be MAXPTR*(MAXPTR+1)/2.
3033 * But since this is much larger than STRLEN, such a line can not be parsed.
3034 * The real maximum is the number of names that fit in a string: STRLEN/2.
3036 #define EGP_MAX (STRLEN/2)
3037 int j, k, nr;
3038 char ***gnames;
3039 bool bSet;
3041 gnames = groups->grpname;
3043 auto names = gmx::splitString(val);
3044 if (names.size() % 2 != 0)
3046 gmx_fatal(FARGS, "The number of groups for %s is odd", option);
3048 nr = groups->grps[egcENER].nr;
3049 bSet = FALSE;
3050 for (size_t i = 0; i < names.size() / 2; i++)
3052 j = 0;
3053 while ((j < nr) &&
3054 gmx_strcasecmp(names[2*i].c_str(), *(gnames[groups->grps[egcENER].nm_ind[j]])))
3056 j++;
3058 if (j == nr)
3060 gmx_fatal(FARGS, "%s in %s is not an energy group\n",
3061 names[2*i].c_str(), option);
3063 k = 0;
3064 while ((k < nr) &&
3065 gmx_strcasecmp(names[2*i+1].c_str(), *(gnames[groups->grps[egcENER].nm_ind[k]])))
3067 k++;
3069 if (k == nr)
3071 gmx_fatal(FARGS, "%s in %s is not an energy group\n",
3072 names[2*i+1].c_str(), option);
3074 if ((j < nr) && (k < nr))
3076 ir->opts.egp_flags[nr*j+k] |= flag;
3077 ir->opts.egp_flags[nr*k+j] |= flag;
3078 bSet = TRUE;
3082 return bSet;
3086 static void make_swap_groups(
3087 t_swapcoords *swap,
3088 t_blocka *grps,
3089 char **gnames)
3091 int ig = -1, i = 0, gind;
3092 t_swapGroup *swapg;
3095 /* Just a quick check here, more thorough checks are in mdrun */
3096 if (strcmp(swap->grp[eGrpSplit0].molname, swap->grp[eGrpSplit1].molname) == 0)
3098 gmx_fatal(FARGS, "The split groups can not both be '%s'.", swap->grp[eGrpSplit0].molname);
3101 /* Get the index atoms of the split0, split1, solvent, and swap groups */
3102 for (ig = 0; ig < swap->ngrp; ig++)
3104 swapg = &swap->grp[ig];
3105 gind = search_string(swap->grp[ig].molname, grps->nr, gnames);
3106 swapg->nat = grps->index[gind+1] - grps->index[gind];
3108 if (swapg->nat > 0)
3110 fprintf(stderr, "%s group '%s' contains %d atoms.\n",
3111 ig < 3 ? eSwapFixedGrp_names[ig] : "Swap",
3112 swap->grp[ig].molname, swapg->nat);
3113 snew(swapg->ind, swapg->nat);
3114 for (i = 0; i < swapg->nat; i++)
3116 swapg->ind[i] = grps->a[grps->index[gind]+i];
3119 else
3121 gmx_fatal(FARGS, "Swap group %s does not contain any atoms.", swap->grp[ig].molname);
3127 static void make_IMD_group(t_IMD *IMDgroup, char *IMDgname, t_blocka *grps, char **gnames)
3129 int ig, i;
3132 ig = search_string(IMDgname, grps->nr, gnames);
3133 IMDgroup->nat = grps->index[ig+1] - grps->index[ig];
3135 if (IMDgroup->nat > 0)
3137 fprintf(stderr, "Group '%s' with %d atoms can be activated for interactive molecular dynamics (IMD).\n",
3138 IMDgname, IMDgroup->nat);
3139 snew(IMDgroup->ind, IMDgroup->nat);
3140 for (i = 0; i < IMDgroup->nat; i++)
3142 IMDgroup->ind[i] = grps->a[grps->index[ig]+i];
3147 void do_index(const char* mdparin, const char *ndx,
3148 gmx_mtop_t *mtop,
3149 bool bVerbose,
3150 t_inputrec *ir,
3151 warninp_t wi)
3153 t_blocka *grps;
3154 gmx_groups_t *groups;
3155 int natoms;
3156 t_symtab *symtab;
3157 t_atoms atoms_all;
3158 char warnbuf[STRLEN], **gnames;
3159 int nr;
3160 real tau_min;
3161 int nstcmin;
3162 int i, j, k, restnm;
3163 bool bExcl, bTable, bAnneal, bRest;
3164 char warn_buf[STRLEN];
3166 if (bVerbose)
3168 fprintf(stderr, "processing index file...\n");
3170 if (ndx == nullptr)
3172 snew(grps, 1);
3173 snew(grps->index, 1);
3174 snew(gnames, 1);
3175 atoms_all = gmx_mtop_global_atoms(mtop);
3176 analyse(&atoms_all, grps, &gnames, FALSE, TRUE);
3177 done_atom(&atoms_all);
3179 else
3181 grps = init_index(ndx, &gnames);
3184 groups = &mtop->groups;
3185 natoms = mtop->natoms;
3186 symtab = &mtop->symtab;
3188 snew(groups->grpname, grps->nr+1);
3190 for (i = 0; (i < grps->nr); i++)
3192 groups->grpname[i] = put_symtab(symtab, gnames[i]);
3194 groups->grpname[i] = put_symtab(symtab, "rest");
3195 restnm = i;
3196 srenew(gnames, grps->nr+1);
3197 gnames[restnm] = *(groups->grpname[i]);
3198 groups->ngrpname = grps->nr+1;
3200 set_warning_line(wi, mdparin, -1);
3202 auto temperatureCouplingTauValues = gmx::splitString(is->tau_t);
3203 auto temperatureCouplingReferenceValues = gmx::splitString(is->ref_t);
3204 auto temperatureCouplingGroupNames = gmx::splitString(is->tcgrps);
3205 if (temperatureCouplingTauValues.size() != temperatureCouplingGroupNames.size() ||
3206 temperatureCouplingReferenceValues.size() != temperatureCouplingGroupNames.size())
3208 gmx_fatal(FARGS, "Invalid T coupling input: %zu groups, %zu ref-t values and "
3209 "%zu tau-t values",
3210 temperatureCouplingGroupNames.size(),
3211 temperatureCouplingReferenceValues.size(),
3212 temperatureCouplingTauValues.size());
3215 const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
3216 do_numbering(natoms, groups, temperatureCouplingGroupNames, grps, gnames, egcTC,
3217 restnm, useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
3218 nr = groups->grps[egcTC].nr;
3219 ir->opts.ngtc = nr;
3220 snew(ir->opts.nrdf, nr);
3221 snew(ir->opts.tau_t, nr);
3222 snew(ir->opts.ref_t, nr);
3223 if (ir->eI == eiBD && ir->bd_fric == 0)
3225 fprintf(stderr, "bd-fric=0, so tau-t will be used as the inverse friction constant(s)\n");
3228 if (useReferenceTemperature)
3230 if (size_t(nr) != temperatureCouplingReferenceValues.size())
3232 gmx_fatal(FARGS, "Not enough ref-t and tau-t values!");
3235 tau_min = 1e20;
3236 convertReals(wi, temperatureCouplingTauValues, "tau-t", ir->opts.tau_t);
3237 for (i = 0; (i < nr); i++)
3239 if ((ir->eI == eiBD) && ir->opts.tau_t[i] <= 0)
3241 sprintf(warn_buf, "With integrator %s tau-t should be larger than 0", ei_names[ir->eI]);
3242 warning_error(wi, warn_buf);
3245 if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
3247 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.");
3250 if (ir->opts.tau_t[i] >= 0)
3252 tau_min = std::min(tau_min, ir->opts.tau_t[i]);
3255 if (ir->etc != etcNO && ir->nsttcouple == -1)
3257 ir->nsttcouple = ir_optimal_nsttcouple(ir);
3260 if (EI_VV(ir->eI))
3262 if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
3264 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");
3266 if (ir->epc == epcMTTK)
3268 if (ir->etc != etcNOSEHOOVER)
3270 gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
3272 else
3274 if (ir->nstpcouple != ir->nsttcouple)
3276 int mincouple = std::min(ir->nstpcouple, ir->nsttcouple);
3277 ir->nstpcouple = ir->nsttcouple = mincouple;
3278 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);
3279 warning_note(wi, warn_buf);
3284 /* velocity verlet with averaged kinetic energy KE = 0.5*(v(t+1/2) - v(t-1/2)) is implemented
3285 primarily for testing purposes, and does not work with temperature coupling other than 1 */
3287 if (ETC_ANDERSEN(ir->etc))
3289 if (ir->nsttcouple != 1)
3291 ir->nsttcouple = 1;
3292 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");
3293 warning_note(wi, warn_buf);
3296 nstcmin = tcouple_min_integration_steps(ir->etc);
3297 if (nstcmin > 1)
3299 if (tau_min/(ir->delta_t*ir->nsttcouple) < nstcmin - 10*GMX_REAL_EPS)
3301 sprintf(warn_buf, "For proper integration of the %s thermostat, tau-t (%g) should be at least %d times larger than nsttcouple*dt (%g)",
3302 ETCOUPLTYPE(ir->etc),
3303 tau_min, nstcmin,
3304 ir->nsttcouple*ir->delta_t);
3305 warning(wi, warn_buf);
3308 convertReals(wi, temperatureCouplingReferenceValues, "ref-t", ir->opts.ref_t);
3309 for (i = 0; (i < nr); i++)
3311 if (ir->opts.ref_t[i] < 0)
3313 gmx_fatal(FARGS, "ref-t for group %d negative", i);
3316 /* set the lambda mc temperature to the md integrator temperature (which should be defined
3317 if we are in this conditional) if mc_temp is negative */
3318 if (ir->expandedvals->mc_temp < 0)
3320 ir->expandedvals->mc_temp = ir->opts.ref_t[0]; /*for now, set to the first reft */
3324 /* Simulated annealing for each group. There are nr groups */
3325 auto simulatedAnnealingGroupNames = gmx::splitString(is->anneal);
3326 if (simulatedAnnealingGroupNames.size() == 1 &&
3327 gmx_strncasecmp(simulatedAnnealingGroupNames[0].c_str(), "N", 1) == 0)
3329 simulatedAnnealingGroupNames.resize(0);
3331 if (!simulatedAnnealingGroupNames.empty() &&
3332 simulatedAnnealingGroupNames.size() != size_t(nr))
3334 gmx_fatal(FARGS, "Not enough annealing values: %zu (for %d groups)\n",
3335 simulatedAnnealingGroupNames.size(), nr);
3337 else
3339 snew(ir->opts.annealing, nr);
3340 snew(ir->opts.anneal_npoints, nr);
3341 snew(ir->opts.anneal_time, nr);
3342 snew(ir->opts.anneal_temp, nr);
3343 for (i = 0; i < nr; i++)
3345 ir->opts.annealing[i] = eannNO;
3346 ir->opts.anneal_npoints[i] = 0;
3347 ir->opts.anneal_time[i] = nullptr;
3348 ir->opts.anneal_temp[i] = nullptr;
3350 if (!simulatedAnnealingGroupNames.empty())
3352 bAnneal = FALSE;
3353 for (i = 0; i < nr; i++)
3355 if (gmx_strncasecmp(simulatedAnnealingGroupNames[i].c_str(), "N", 1) == 0)
3357 ir->opts.annealing[i] = eannNO;
3359 else if (gmx_strncasecmp(simulatedAnnealingGroupNames[i].c_str(), "S", 1) == 0)
3361 ir->opts.annealing[i] = eannSINGLE;
3362 bAnneal = TRUE;
3364 else if (gmx_strncasecmp(simulatedAnnealingGroupNames[i].c_str(), "P", 1) == 0)
3366 ir->opts.annealing[i] = eannPERIODIC;
3367 bAnneal = TRUE;
3370 if (bAnneal)
3372 /* Read the other fields too */
3373 auto simulatedAnnealingPoints = gmx::splitString(is->anneal_npoints);
3374 if (simulatedAnnealingPoints.size() != simulatedAnnealingGroupNames.size())
3376 gmx_fatal(FARGS, "Found %zu annealing-npoints values for %zu groups\n",
3377 simulatedAnnealingPoints.size(), simulatedAnnealingGroupNames.size());
3379 convertInts(wi, simulatedAnnealingPoints, "annealing points", ir->opts.anneal_npoints);
3380 for (k = 0, i = 0; i < nr; i++)
3382 if (ir->opts.anneal_npoints[i] == 1)
3384 gmx_fatal(FARGS, "Please specify at least a start and an end point for annealing\n");
3386 snew(ir->opts.anneal_time[i], ir->opts.anneal_npoints[i]);
3387 snew(ir->opts.anneal_temp[i], ir->opts.anneal_npoints[i]);
3388 k += ir->opts.anneal_npoints[i];
3391 auto simulatedAnnealingTimes = gmx::splitString(is->anneal_time);
3392 if (simulatedAnnealingTimes.size() != size_t(k))
3394 gmx_fatal(FARGS, "Found %zu annealing-time values, wanted %d\n",
3395 simulatedAnnealingTimes.size(), k);
3397 auto simulatedAnnealingTemperatures = gmx::splitString(is->anneal_temp);
3398 if (simulatedAnnealingTemperatures.size() != size_t(k))
3400 gmx_fatal(FARGS, "Found %zu annealing-temp values, wanted %d\n",
3401 simulatedAnnealingTemperatures.size(), k);
3404 convertReals(wi, simulatedAnnealingTimes, "anneal-time", ir->opts.anneal_time[i]);
3405 convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp", ir->opts.anneal_temp[i]);
3406 for (i = 0, k = 0; i < nr; i++)
3408 for (j = 0; j < ir->opts.anneal_npoints[i]; j++)
3410 if (j == 0)
3412 if (ir->opts.anneal_time[i][0] > (ir->init_t+GMX_REAL_EPS))
3414 gmx_fatal(FARGS, "First time point for annealing > init_t.\n");
3417 else
3419 /* j>0 */
3420 if (ir->opts.anneal_time[i][j] < ir->opts.anneal_time[i][j-1])
3422 gmx_fatal(FARGS, "Annealing timepoints out of order: t=%f comes after t=%f\n",
3423 ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j-1]);
3426 if (ir->opts.anneal_temp[i][j] < 0)
3428 gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n", ir->opts.anneal_temp[i][j]);
3430 k++;
3433 /* Print out some summary information, to make sure we got it right */
3434 for (i = 0, k = 0; i < nr; i++)
3436 if (ir->opts.annealing[i] != eannNO)
3438 j = groups->grps[egcTC].nm_ind[i];
3439 fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
3440 *(groups->grpname[j]), eann_names[ir->opts.annealing[i]],
3441 ir->opts.anneal_npoints[i]);
3442 fprintf(stderr, "Time (ps) Temperature (K)\n");
3443 /* All terms except the last one */
3444 for (j = 0; j < (ir->opts.anneal_npoints[i]-1); j++)
3446 fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3449 /* Finally the last one */
3450 j = ir->opts.anneal_npoints[i]-1;
3451 if (ir->opts.annealing[i] == eannSINGLE)
3453 fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3455 else
3457 fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3458 if (std::fabs(ir->opts.anneal_temp[i][j]-ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS)
3460 warning_note(wi, "There is a temperature jump when your annealing loops back.\n");
3469 if (ir->bPull)
3471 make_pull_groups(ir->pull, is->pull_grp, grps, gnames);
3473 make_pull_coords(ir->pull);
3476 if (ir->bRot)
3478 make_rotation_groups(ir->rot, is->rot_grp, grps, gnames);
3481 if (ir->eSwapCoords != eswapNO)
3483 make_swap_groups(ir->swap, grps, gnames);
3486 /* Make indices for IMD session */
3487 if (ir->bIMD)
3489 make_IMD_group(ir->imd, is->imd_grp, grps, gnames);
3492 auto accelerations = gmx::splitString(is->acc);
3493 auto accelerationGroupNames = gmx::splitString(is->accgrps);
3494 if (accelerationGroupNames.size() * DIM != accelerations.size())
3496 gmx_fatal(FARGS, "Invalid Acceleration input: %d groups and %d acc. values",
3497 accelerationGroupNames.size(), accelerations.size());
3499 do_numbering(natoms, groups, accelerationGroupNames, grps, gnames, egcACC,
3500 restnm, egrptpALL_GENREST, bVerbose, wi);
3501 nr = groups->grps[egcACC].nr;
3502 snew(ir->opts.acc, nr);
3503 ir->opts.ngacc = nr;
3505 convertRvecs(wi, accelerations, "anneal-time", ir->opts.acc);
3507 auto freezeDims = gmx::splitString(is->frdim);
3508 auto freezeGroupNames = gmx::splitString(is->freeze);
3509 if (freezeDims.size() != DIM * freezeGroupNames.size())
3511 gmx_fatal(FARGS, "Invalid Freezing input: %d groups and %d freeze values",
3512 freezeGroupNames.size(), freezeDims.size());
3514 do_numbering(natoms, groups, freezeGroupNames, grps, gnames, egcFREEZE,
3515 restnm, egrptpALL_GENREST, bVerbose, wi);
3516 nr = groups->grps[egcFREEZE].nr;
3517 ir->opts.ngfrz = nr;
3518 snew(ir->opts.nFreeze, nr);
3519 for (i = k = 0; (size_t(i) < freezeGroupNames.size()); i++)
3521 for (j = 0; (j < DIM); j++, k++)
3523 ir->opts.nFreeze[i][j] = static_cast<int>(gmx_strncasecmp(freezeDims[k].c_str(), "Y", 1) == 0);
3524 if (!ir->opts.nFreeze[i][j])
3526 if (gmx_strncasecmp(freezeDims[k].c_str(), "N", 1) != 0)
3528 sprintf(warnbuf, "Please use Y(ES) or N(O) for freezedim only "
3529 "(not %s)", freezeDims[k].c_str());
3530 warning(wi, warn_buf);
3535 for (; (i < nr); i++)
3537 for (j = 0; (j < DIM); j++)
3539 ir->opts.nFreeze[i][j] = 0;
3543 auto energyGroupNames = gmx::splitString(is->energy);
3544 do_numbering(natoms, groups, energyGroupNames, grps, gnames, egcENER,
3545 restnm, egrptpALL_GENREST, bVerbose, wi);
3546 add_wall_energrps(groups, ir->nwall, symtab);
3547 ir->opts.ngener = groups->grps[egcENER].nr;
3548 auto vcmGroupNames = gmx::splitString(is->vcm);
3549 bRest =
3550 do_numbering(natoms, groups, vcmGroupNames, grps, gnames, egcVCM,
3551 restnm, vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
3552 if (bRest)
3554 warning(wi, "Some atoms are not part of any center of mass motion removal group.\n"
3555 "This may lead to artifacts.\n"
3556 "In most cases one should use one group for the whole system.");
3559 /* Now we have filled the freeze struct, so we can calculate NRDF */
3560 calc_nrdf(mtop, ir, gnames);
3562 auto user1GroupNames = gmx::splitString(is->user1);
3563 do_numbering(natoms, groups, user1GroupNames, grps, gnames, egcUser1,
3564 restnm, egrptpALL_GENREST, bVerbose, wi);
3565 auto user2GroupNames = gmx::splitString(is->user2);
3566 do_numbering(natoms, groups, user2GroupNames, grps, gnames, egcUser2,
3567 restnm, egrptpALL_GENREST, bVerbose, wi);
3568 auto compressedXGroupNames = gmx::splitString(is->x_compressed_groups);
3569 do_numbering(natoms, groups, compressedXGroupNames, grps, gnames, egcCompressedX,
3570 restnm, egrptpONE, bVerbose, wi);
3571 auto orirefFitGroupNames = gmx::splitString(is->orirefitgrp);
3572 do_numbering(natoms, groups, orirefFitGroupNames, grps, gnames, egcORFIT,
3573 restnm, egrptpALL_GENREST, bVerbose, wi);
3575 /* QMMM input processing */
3576 auto qmGroupNames = gmx::splitString(is->QMMM);
3577 auto qmMethods = gmx::splitString(is->QMmethod);
3578 auto qmBasisSets = gmx::splitString(is->QMbasis);
3579 if (qmMethods.size() != qmGroupNames.size() ||
3580 qmBasisSets.size() != qmGroupNames.size())
3582 gmx_fatal(FARGS, "Invalid QMMM input: %zu groups %zu basissets"
3583 " and %zu methods\n", qmGroupNames.size(),
3584 qmBasisSets.size(), qmMethods.size());
3586 /* group rest, if any, is always MM! */
3587 do_numbering(natoms, groups, qmGroupNames, grps, gnames, egcQMMM,
3588 restnm, egrptpALL_GENREST, bVerbose, wi);
3589 nr = qmGroupNames.size(); /*atoms->grps[egcQMMM].nr;*/
3590 ir->opts.ngQM = qmGroupNames.size();
3591 snew(ir->opts.QMmethod, nr);
3592 snew(ir->opts.QMbasis, nr);
3593 for (i = 0; i < nr; i++)
3595 /* input consists of strings: RHF CASSCF PM3 .. These need to be
3596 * converted to the corresponding enum in names.c
3598 ir->opts.QMmethod[i] = search_QMstring(qmMethods[i].c_str(), eQMmethodNR,
3599 eQMmethod_names);
3600 ir->opts.QMbasis[i] = search_QMstring(qmBasisSets[i].c_str(), eQMbasisNR,
3601 eQMbasis_names);
3604 auto qmMultiplicities = gmx::splitString(is->QMmult);
3605 auto qmCharges = gmx::splitString(is->QMcharge);
3606 auto qmbSH = gmx::splitString(is->bSH);
3607 snew(ir->opts.QMmult, nr);
3608 snew(ir->opts.QMcharge, nr);
3609 snew(ir->opts.bSH, nr);
3610 convertInts(wi, qmMultiplicities, "QMmult", ir->opts.QMmult);
3611 convertInts(wi, qmCharges, "QMcharge", ir->opts.QMcharge);
3612 convertYesNos(wi, qmbSH, "bSH", ir->opts.bSH);
3614 auto CASelectrons = gmx::splitString(is->CASelectrons);
3615 auto CASorbitals = gmx::splitString(is->CASorbitals);
3616 snew(ir->opts.CASelectrons, nr);
3617 snew(ir->opts.CASorbitals, nr);
3618 convertInts(wi, CASelectrons, "CASelectrons", ir->opts.CASelectrons);
3619 convertInts(wi, CASorbitals, "CASOrbitals", ir->opts.CASorbitals);
3621 auto SAon = gmx::splitString(is->SAon);
3622 auto SAoff = gmx::splitString(is->SAoff);
3623 auto SAsteps = gmx::splitString(is->SAsteps);
3624 snew(ir->opts.SAon, nr);
3625 snew(ir->opts.SAoff, nr);
3626 snew(ir->opts.SAsteps, nr);
3627 convertInts(wi, SAon, "SAon", ir->opts.SAon);
3628 convertInts(wi, SAoff, "SAoff", ir->opts.SAoff);
3629 convertInts(wi, SAsteps, "SAsteps", ir->opts.SAsteps);
3631 /* end of QMMM input */
3633 if (bVerbose)
3635 for (i = 0; (i < egcNR); i++)
3637 fprintf(stderr, "%-16s has %d element(s):", gtypes[i], groups->grps[i].nr);
3638 for (j = 0; (j < groups->grps[i].nr); j++)
3640 fprintf(stderr, " %s", *(groups->grpname[groups->grps[i].nm_ind[j]]));
3642 fprintf(stderr, "\n");
3646 nr = groups->grps[egcENER].nr;
3647 snew(ir->opts.egp_flags, nr*nr);
3649 bExcl = do_egp_flag(ir, groups, "energygrp-excl", is->egpexcl, EGP_EXCL);
3650 if (bExcl && ir->cutoff_scheme == ecutsVERLET)
3652 warning_error(wi, "Energy group exclusions are not (yet) implemented for the Verlet scheme");
3654 if (bExcl && EEL_FULL(ir->coulombtype))
3656 warning(wi, "Can not exclude the lattice Coulomb energy between energy groups");
3659 bTable = do_egp_flag(ir, groups, "energygrp-table", is->egptable, EGP_TABLE);
3660 if (bTable && !(ir->vdwtype == evdwUSER) &&
3661 !(ir->coulombtype == eelUSER) && !(ir->coulombtype == eelPMEUSER) &&
3662 !(ir->coulombtype == eelPMEUSERSWITCH))
3664 gmx_fatal(FARGS, "Can only have energy group pair tables in combination with user tables for VdW and/or Coulomb");
3667 for (i = 0; (i < grps->nr); i++)
3669 sfree(gnames[i]);
3671 sfree(gnames);
3672 done_blocka(grps);
3673 sfree(grps);
3679 static void check_disre(gmx_mtop_t *mtop)
3681 gmx_ffparams_t *ffparams;
3682 t_functype *functype;
3683 t_iparams *ip;
3684 int i, ndouble, ftype;
3685 int label, old_label;
3687 if (gmx_mtop_ftype_count(mtop, F_DISRES) > 0)
3689 ffparams = &mtop->ffparams;
3690 functype = ffparams->functype;
3691 ip = ffparams->iparams;
3692 ndouble = 0;
3693 old_label = -1;
3694 for (i = 0; i < ffparams->ntypes; i++)
3696 ftype = functype[i];
3697 if (ftype == F_DISRES)
3699 label = ip[i].disres.label;
3700 if (label == old_label)
3702 fprintf(stderr, "Distance restraint index %d occurs twice\n", label);
3703 ndouble++;
3705 old_label = label;
3708 if (ndouble > 0)
3710 gmx_fatal(FARGS, "Found %d double distance restraint indices,\n"
3711 "probably the parameters for multiple pairs in one restraint "
3712 "are not identical\n", ndouble);
3717 static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys,
3718 bool posres_only,
3719 ivec AbsRef)
3721 int d, g, i;
3722 gmx_mtop_ilistloop_t iloop;
3723 const InteractionList *ilist;
3724 int nmol;
3725 t_iparams *pr;
3727 clear_ivec(AbsRef);
3729 if (!posres_only)
3731 /* Check the COM */
3732 for (d = 0; d < DIM; d++)
3734 AbsRef[d] = (d < ndof_com(ir) ? 0 : 1);
3736 /* Check for freeze groups */
3737 for (g = 0; g < ir->opts.ngfrz; g++)
3739 for (d = 0; d < DIM; d++)
3741 if (ir->opts.nFreeze[g][d] != 0)
3743 AbsRef[d] = 1;
3749 /* Check for position restraints */
3750 iloop = gmx_mtop_ilistloop_init(sys);
3751 while (gmx_mtop_ilistloop_next(iloop, &ilist, &nmol))
3753 if (nmol > 0 &&
3754 (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
3756 for (i = 0; i < ilist[F_POSRES].size(); i += 2)
3758 pr = &sys->ffparams.iparams[ilist[F_POSRES].iatoms[i]];
3759 for (d = 0; d < DIM; d++)
3761 if (pr->posres.fcA[d] != 0)
3763 AbsRef[d] = 1;
3767 for (i = 0; i < ilist[F_FBPOSRES].size(); i += 2)
3769 /* Check for flat-bottom posres */
3770 pr = &sys->ffparams.iparams[ilist[F_FBPOSRES].iatoms[i]];
3771 if (pr->fbposres.k != 0)
3773 switch (pr->fbposres.geom)
3775 case efbposresSPHERE:
3776 AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1;
3777 break;
3778 case efbposresCYLINDERX:
3779 AbsRef[YY] = AbsRef[ZZ] = 1;
3780 break;
3781 case efbposresCYLINDERY:
3782 AbsRef[XX] = AbsRef[ZZ] = 1;
3783 break;
3784 case efbposresCYLINDER:
3785 /* efbposres is a synonym for efbposresCYLINDERZ for backwards compatibility */
3786 case efbposresCYLINDERZ:
3787 AbsRef[XX] = AbsRef[YY] = 1;
3788 break;
3789 case efbposresX: /* d=XX */
3790 case efbposresY: /* d=YY */
3791 case efbposresZ: /* d=ZZ */
3792 d = pr->fbposres.geom - efbposresX;
3793 AbsRef[d] = 1;
3794 break;
3795 default:
3796 gmx_fatal(FARGS, " Invalid geometry for flat-bottom position restraint.\n"
3797 "Expected nr between 1 and %d. Found %d\n", efbposresNR-1,
3798 pr->fbposres.geom);
3805 return (AbsRef[XX] != 0 && AbsRef[YY] != 0 && AbsRef[ZZ] != 0);
3808 static void
3809 check_combination_rule_differences(const gmx_mtop_t *mtop, int state,
3810 bool *bC6ParametersWorkWithGeometricRules,
3811 bool *bC6ParametersWorkWithLBRules,
3812 bool *bLBRulesPossible)
3814 int ntypes, tpi, tpj;
3815 int *typecount;
3816 real tol;
3817 double c6i, c6j, c12i, c12j;
3818 double c6, c6_geometric, c6_LB;
3819 double sigmai, sigmaj, epsi, epsj;
3820 bool bCanDoLBRules, bCanDoGeometricRules;
3821 const char *ptr;
3823 /* A tolerance of 1e-5 seems reasonable for (possibly hand-typed)
3824 * force-field floating point parameters.
3826 tol = 1e-5;
3827 ptr = getenv("GMX_LJCOMB_TOL");
3828 if (ptr != nullptr)
3830 double dbl;
3831 double gmx_unused canary;
3833 if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
3835 gmx_fatal(FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
3837 tol = dbl;
3840 *bC6ParametersWorkWithLBRules = TRUE;
3841 *bC6ParametersWorkWithGeometricRules = TRUE;
3842 bCanDoLBRules = TRUE;
3843 ntypes = mtop->ffparams.atnr;
3844 snew(typecount, ntypes);
3845 gmx_mtop_count_atomtypes(mtop, state, typecount);
3846 *bLBRulesPossible = TRUE;
3847 for (tpi = 0; tpi < ntypes; ++tpi)
3849 c6i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c6;
3850 c12i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c12;
3851 for (tpj = tpi; tpj < ntypes; ++tpj)
3853 c6j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
3854 c12j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
3855 c6 = mtop->ffparams.iparams[ntypes * tpi + tpj].lj.c6;
3856 c6_geometric = std::sqrt(c6i * c6j);
3857 if (!gmx_numzero(c6_geometric))
3859 if (!gmx_numzero(c12i) && !gmx_numzero(c12j))
3861 sigmai = gmx::sixthroot(c12i / c6i);
3862 sigmaj = gmx::sixthroot(c12j / c6j);
3863 epsi = c6i * c6i /(4.0 * c12i);
3864 epsj = c6j * c6j /(4.0 * c12j);
3865 c6_LB = 4.0 * std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj));
3867 else
3869 *bLBRulesPossible = FALSE;
3870 c6_LB = c6_geometric;
3872 bCanDoLBRules = gmx_within_tol(c6_LB, c6, tol);
3875 if (!bCanDoLBRules)
3877 *bC6ParametersWorkWithLBRules = FALSE;
3880 bCanDoGeometricRules = gmx_within_tol(c6_geometric, c6, tol);
3882 if (!bCanDoGeometricRules)
3884 *bC6ParametersWorkWithGeometricRules = FALSE;
3888 sfree(typecount);
3891 static void
3892 check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop,
3893 warninp_t wi)
3895 bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
3897 check_combination_rule_differences(mtop, 0,
3898 &bC6ParametersWorkWithGeometricRules,
3899 &bC6ParametersWorkWithLBRules,
3900 &bLBRulesPossible);
3901 if (ir->ljpme_combination_rule == eljpmeLB)
3903 if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
3905 warning(wi, "You are using arithmetic-geometric combination rules "
3906 "in LJ-PME, but your non-bonded C6 parameters do not "
3907 "follow these rules.");
3910 else
3912 if (!bC6ParametersWorkWithGeometricRules)
3914 if (ir->eDispCorr != edispcNO)
3916 warning_note(wi, "You are using geometric combination rules in "
3917 "LJ-PME, but your non-bonded C6 parameters do "
3918 "not follow these rules. "
3919 "This will introduce very small errors in the forces and energies in "
3920 "your simulations. Dispersion correction will correct total energy "
3921 "and/or pressure for isotropic systems, but not forces or surface tensions.");
3923 else
3925 warning_note(wi, "You are using geometric combination rules in "
3926 "LJ-PME, but your non-bonded C6 parameters do "
3927 "not follow these rules. "
3928 "This will introduce very small errors in the forces and energies in "
3929 "your simulations. If your system is homogeneous, consider using dispersion correction "
3930 "for the total energy and pressure.");
3936 void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
3937 warninp_t wi)
3939 char err_buf[STRLEN];
3940 int i, m, c, nmol;
3941 bool bCharge, bAcc;
3942 real *mgrp, mt;
3943 rvec acc;
3944 gmx_mtop_atomloop_block_t aloopb;
3945 gmx_mtop_atomloop_all_t aloop;
3946 ivec AbsRef;
3947 char warn_buf[STRLEN];
3949 set_warning_line(wi, mdparin, -1);
3951 if (ir->cutoff_scheme == ecutsVERLET &&
3952 ir->verletbuf_tol > 0 &&
3953 ir->nstlist > 1 &&
3954 ((EI_MD(ir->eI) || EI_SD(ir->eI)) &&
3955 (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
3957 /* Check if a too small Verlet buffer might potentially
3958 * cause more drift than the thermostat can couple off.
3960 /* Temperature error fraction for warning and suggestion */
3961 const real T_error_warn = 0.002;
3962 const real T_error_suggest = 0.001;
3963 /* For safety: 2 DOF per atom (typical with constraints) */
3964 const real nrdf_at = 2;
3965 real T, tau, max_T_error;
3966 int i;
3968 T = 0;
3969 tau = 0;
3970 for (i = 0; i < ir->opts.ngtc; i++)
3972 T = std::max(T, ir->opts.ref_t[i]);
3973 tau = std::max(tau, ir->opts.tau_t[i]);
3975 if (T > 0)
3977 /* This is a worst case estimate of the temperature error,
3978 * assuming perfect buffer estimation and no cancelation
3979 * of errors. The factor 0.5 is because energy distributes
3980 * equally over Ekin and Epot.
3982 max_T_error = 0.5*tau*ir->verletbuf_tol/(nrdf_at*BOLTZ*T);
3983 if (max_T_error > T_error_warn)
3985 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.",
3986 ir->verletbuf_tol, T, tau,
3987 100*max_T_error,
3988 100*T_error_suggest,
3989 ir->verletbuf_tol*T_error_suggest/max_T_error);
3990 warning(wi, warn_buf);
3995 if (ETC_ANDERSEN(ir->etc))
3997 int i;
3999 for (i = 0; i < ir->opts.ngtc; i++)
4001 sprintf(err_buf, "all tau_t must currently be equal using Andersen temperature control, violated for group %d", i);
4002 CHECK(ir->opts.tau_t[0] != ir->opts.tau_t[i]);
4003 sprintf(err_buf, "all tau_t must be positive using Andersen temperature control, tau_t[%d]=%10.6f",
4004 i, ir->opts.tau_t[i]);
4005 CHECK(ir->opts.tau_t[i] < 0);
4008 if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
4010 for (i = 0; i < ir->opts.ngtc; i++)
4012 int nsteps = gmx::roundToInt(ir->opts.tau_t[i]/ir->delta_t);
4013 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);
4014 CHECK(nsteps % ir->nstcomm != 0);
4019 if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD &&
4020 ir->comm_mode == ecmNO &&
4021 !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) &&
4022 !ETC_ANDERSEN(ir->etc))
4024 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");
4027 /* Check for pressure coupling with absolute position restraints */
4028 if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
4030 absolute_reference(ir, sys, TRUE, AbsRef);
4032 for (m = 0; m < DIM; m++)
4034 if (AbsRef[m] && norm2(ir->compress[m]) > 0)
4036 warning(wi, "You are using pressure coupling with absolute position restraints, this will give artifacts. Use the refcoord_scaling option.");
4037 break;
4043 bCharge = FALSE;
4044 aloopb = gmx_mtop_atomloop_block_init(sys);
4045 const t_atom *atom;
4046 while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol))
4048 if (atom->q != 0 || atom->qB != 0)
4050 bCharge = TRUE;
4054 if (!bCharge)
4056 if (EEL_FULL(ir->coulombtype))
4058 sprintf(err_buf,
4059 "You are using full electrostatics treatment %s for a system without charges.\n"
4060 "This costs a lot of performance for just processing zeros, consider using %s instead.\n",
4061 EELTYPE(ir->coulombtype), EELTYPE(eelCUT));
4062 warning(wi, err_buf);
4065 else
4067 if (ir->coulombtype == eelCUT && ir->rcoulomb > 0)
4069 sprintf(err_buf,
4070 "You are using a plain Coulomb cut-off, which might produce artifacts.\n"
4071 "You might want to consider using %s electrostatics.\n",
4072 EELTYPE(eelPME));
4073 warning_note(wi, err_buf);
4077 /* Check if combination rules used in LJ-PME are the same as in the force field */
4078 if (EVDW_PME(ir->vdwtype))
4080 check_combination_rules(ir, sys, wi);
4083 /* Generalized reaction field */
4084 if (ir->opts.ngtc == 0)
4086 sprintf(err_buf, "No temperature coupling while using coulombtype %s",
4087 eel_names[eelGRF]);
4088 CHECK(ir->coulombtype == eelGRF);
4090 else
4092 sprintf(err_buf, "When using coulombtype = %s"
4093 " ref-t for temperature coupling should be > 0",
4094 eel_names[eelGRF]);
4095 CHECK((ir->coulombtype == eelGRF) && (ir->opts.ref_t[0] <= 0));
4098 bAcc = FALSE;
4099 for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
4101 for (m = 0; (m < DIM); m++)
4103 if (fabs(ir->opts.acc[i][m]) > 1e-6)
4105 bAcc = TRUE;
4109 if (bAcc)
4111 clear_rvec(acc);
4112 snew(mgrp, sys->groups.grps[egcACC].nr);
4113 aloop = gmx_mtop_atomloop_all_init(sys);
4114 const t_atom *atom;
4115 while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
4117 mgrp[getGroupType(&sys->groups, egcACC, i)] += atom->m;
4119 mt = 0.0;
4120 for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
4122 for (m = 0; (m < DIM); m++)
4124 acc[m] += ir->opts.acc[i][m]*mgrp[i];
4126 mt += mgrp[i];
4128 for (m = 0; (m < DIM); m++)
4130 if (fabs(acc[m]) > 1e-6)
4132 const char *dim[DIM] = { "X", "Y", "Z" };
4133 fprintf(stderr,
4134 "Net Acceleration in %s direction, will %s be corrected\n",
4135 dim[m], ir->nstcomm != 0 ? "" : "not");
4136 if (ir->nstcomm != 0 && m < ndof_com(ir))
4138 acc[m] /= mt;
4139 for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
4141 ir->opts.acc[i][m] -= acc[m];
4146 sfree(mgrp);
4149 if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0 &&
4150 !gmx_within_tol(sys->ffparams.reppow, 12.0, 10*GMX_DOUBLE_EPS))
4152 gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12");
4155 if (ir->bPull)
4157 bool bWarned;
4159 bWarned = FALSE;
4160 for (i = 0; i < ir->pull->ncoord && !bWarned; i++)
4162 if (ir->pull->coord[i].group[0] == 0 ||
4163 ir->pull->coord[i].group[1] == 0)
4165 absolute_reference(ir, sys, FALSE, AbsRef);
4166 for (m = 0; m < DIM; m++)
4168 if (ir->pull->coord[i].dim[m] && !AbsRef[m])
4170 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.");
4171 bWarned = TRUE;
4172 break;
4178 for (i = 0; i < 3; i++)
4180 for (m = 0; m <= i; m++)
4182 if ((ir->epc != epcNO && ir->compress[i][m] != 0) ||
4183 ir->deform[i][m] != 0)
4185 for (c = 0; c < ir->pull->ncoord; c++)
4187 if (ir->pull->coord[c].eGeom == epullgDIRPBC &&
4188 ir->pull->coord[c].vec[m] != 0)
4190 gmx_fatal(FARGS, "Can not have dynamic box while using pull geometry '%s' (dim %c)", EPULLGEOM(ir->pull->coord[c].eGeom), 'x'+m);
4198 check_disre(sys);
4201 void double_check(t_inputrec *ir, matrix box,
4202 bool bHasNormalConstraints,
4203 bool bHasAnyConstraints,
4204 warninp_t wi)
4206 real min_size;
4207 char warn_buf[STRLEN];
4208 const char *ptr;
4210 ptr = check_box(ir->ePBC, box);
4211 if (ptr)
4213 warning_error(wi, ptr);
4216 if (bHasNormalConstraints && ir->eConstrAlg == econtSHAKE)
4218 if (ir->shake_tol <= 0.0)
4220 sprintf(warn_buf, "ERROR: shake-tol must be > 0 instead of %g\n",
4221 ir->shake_tol);
4222 warning_error(wi, warn_buf);
4226 if ( (ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
4228 /* If we have Lincs constraints: */
4229 if (ir->eI == eiMD && ir->etc == etcNO &&
4230 ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
4232 sprintf(warn_buf, "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
4233 warning_note(wi, warn_buf);
4236 if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8))
4238 sprintf(warn_buf, "For accurate %s with LINCS constraints, lincs-order should be 8 or more.", ei_names[ir->eI]);
4239 warning_note(wi, warn_buf);
4241 if (ir->epc == epcMTTK)
4243 warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
4247 if (bHasAnyConstraints && ir->epc == epcMTTK)
4249 warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
4252 if (ir->LincsWarnAngle > 90.0)
4254 sprintf(warn_buf, "lincs-warnangle can not be larger than 90 degrees, setting it to 90.\n");
4255 warning(wi, warn_buf);
4256 ir->LincsWarnAngle = 90.0;
4259 if (ir->ePBC != epbcNONE)
4261 if (ir->nstlist == 0)
4263 warning(wi, "With nstlist=0 atoms are only put into the box at step 0, therefore drifting atoms might cause the simulation to crash.");
4265 if (ir->ns_type == ensGRID)
4267 if (gmx::square(ir->rlist) >= max_cutoff2(ir->ePBC, box))
4269 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");
4270 warning_error(wi, warn_buf);
4273 else
4275 min_size = std::min(box[XX][XX], std::min(box[YY][YY], box[ZZ][ZZ]));
4276 if (2*ir->rlist >= min_size)
4278 sprintf(warn_buf, "ERROR: One of the box lengths is smaller than twice the cut-off length. Increase the box size or decrease rlist.");
4279 warning_error(wi, warn_buf);
4280 if (TRICLINIC(box))
4282 fprintf(stderr, "Grid search might allow larger cut-off's than simple search with triclinic boxes.");
4289 void check_chargegroup_radii(const gmx_mtop_t *mtop, const t_inputrec *ir,
4290 rvec *x,
4291 warninp_t wi)
4293 real rvdw1, rvdw2, rcoul1, rcoul2;
4294 char warn_buf[STRLEN];
4296 calc_chargegroup_radii(mtop, x, &rvdw1, &rvdw2, &rcoul1, &rcoul2);
4298 if (rvdw1 > 0)
4300 printf("Largest charge group radii for Van der Waals: %5.3f, %5.3f nm\n",
4301 rvdw1, rvdw2);
4303 if (rcoul1 > 0)
4305 printf("Largest charge group radii for Coulomb: %5.3f, %5.3f nm\n",
4306 rcoul1, rcoul2);
4309 if (ir->rlist > 0)
4311 if (rvdw1 + rvdw2 > ir->rlist ||
4312 rcoul1 + rcoul2 > ir->rlist)
4314 sprintf(warn_buf,
4315 "The sum of the two largest charge group radii (%f) "
4316 "is larger than rlist (%f)\n",
4317 std::max(rvdw1+rvdw2, rcoul1+rcoul2), ir->rlist);
4318 warning(wi, warn_buf);
4320 else
4322 /* Here we do not use the zero at cut-off macro,
4323 * since user defined interactions might purposely
4324 * not be zero at the cut-off.
4326 if (ir_vdw_is_zero_at_cutoff(ir) &&
4327 rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
4329 sprintf(warn_buf, "The sum of the two largest charge group "
4330 "radii (%f) is larger than rlist (%f) - rvdw (%f).\n"
4331 "With exact cut-offs, better performance can be "
4332 "obtained with cutoff-scheme = %s, because it "
4333 "does not use charge groups at all.",
4334 rvdw1+rvdw2,
4335 ir->rlist, ir->rvdw,
4336 ecutscheme_names[ecutsVERLET]);
4337 if (ir_NVE(ir))
4339 warning(wi, warn_buf);
4341 else
4343 warning_note(wi, warn_buf);
4346 if (ir_coulomb_is_zero_at_cutoff(ir) &&
4347 rcoul1 + rcoul2 > ir->rlist - ir->rcoulomb)
4349 sprintf(warn_buf, "The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rcoulomb (%f).\n"
4350 "With exact cut-offs, better performance can be obtained with cutoff-scheme = %s, because it does not use charge groups at all.",
4351 rcoul1+rcoul2,
4352 ir->rlist, ir->rcoulomb,
4353 ecutscheme_names[ecutsVERLET]);
4354 if (ir_NVE(ir))
4356 warning(wi, warn_buf);
4358 else
4360 warning_note(wi, warn_buf);