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,2019, 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.
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/toputil.h"
55 #include "gromacs/math/functions.h"
56 #include "gromacs/math/units.h"
57 #include "gromacs/math/vec.h"
58 #include "gromacs/mdlib/calc_verletbuf.h"
59 #include "gromacs/mdrun/mdmodules.h"
60 #include "gromacs/mdtypes/inputrec.h"
61 #include "gromacs/mdtypes/md_enums.h"
62 #include "gromacs/mdtypes/pull_params.h"
63 #include "gromacs/options/options.h"
64 #include "gromacs/options/treesupport.h"
65 #include "gromacs/pbcutil/pbc.h"
66 #include "gromacs/selection/indexutil.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/keyvaluetreemdpwriter.h"
82 #include "gromacs/utility/keyvaluetreetransform.h"
83 #include "gromacs/utility/mdmodulenotification.h"
84 #include "gromacs/utility/smalloc.h"
85 #include "gromacs/utility/strconvert.h"
86 #include "gromacs/utility/stringcompare.h"
87 #include "gromacs/utility/stringutil.h"
88 #include "gromacs/utility/textwriter.h"
93 /* Resource parameters
94 * Do not change any of these until you read the instruction
95 * in readinp.h. Some cpp's do not take spaces after the backslash
96 * (like the c-shell), which will give you a very weird compiler
100 typedef struct t_inputrec_strings
102 char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN],
103 acc[STRLEN], accgrps[STRLEN], freeze[STRLEN], frdim[STRLEN],
104 energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], x_compressed_groups[STRLEN],
105 couple_moltype[STRLEN], orirefitgrp[STRLEN], egptable[STRLEN], egpexcl[STRLEN],
106 wall_atomtype[STRLEN], wall_density[STRLEN], deform[STRLEN], QMMM[STRLEN],
108 char fep_lambda[efptNR][STRLEN];
109 char lambda_weights[STRLEN];
112 char anneal[STRLEN], anneal_npoints[STRLEN],
113 anneal_time[STRLEN], anneal_temp[STRLEN];
114 char QMmethod[STRLEN], QMbasis[STRLEN], QMcharge[STRLEN], QMmult[STRLEN],
115 bSH[STRLEN], CASorbitals[STRLEN], CASelectrons[STRLEN], SAon[STRLEN],
116 SAoff[STRLEN], SAsteps[STRLEN];
118 } gmx_inputrec_strings;
120 static gmx_inputrec_strings *is = nullptr;
122 void init_inputrec_strings()
126 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.");
131 void done_inputrec_strings()
139 egrptpALL, /* All particles have to be a member of a group. */
140 egrptpALL_GENREST, /* A rest group with name is generated for particles *
141 * that are not part of any group. */
142 egrptpPART, /* As egrptpALL_GENREST, but no name is generated *
143 * for the rest group. */
144 egrptpONE /* Merge all selected groups into one group, *
145 * make a rest group for the remaining particles. */
148 static const char *constraints[eshNR+1] = {
149 "none", "h-bonds", "all-bonds", "h-angles", "all-angles", nullptr
152 static const char *couple_lam[ecouplamNR+1] = {
153 "vdw-q", "vdw", "q", "none", nullptr
156 static void GetSimTemps(int ntemps, t_simtemp *simtemp, double *temperature_lambdas)
161 for (i = 0; i < ntemps; i++)
163 /* simple linear scaling -- allows more control */
164 if (simtemp->eSimTempScale == esimtempLINEAR)
166 simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*temperature_lambdas[i];
168 else if (simtemp->eSimTempScale == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */
170 simtemp->temperatures[i] = simtemp->simtemp_low * std::pow(simtemp->simtemp_high/simtemp->simtemp_low, static_cast<real>((1.0*i)/(ntemps-1)));
172 else if (simtemp->eSimTempScale == esimtempEXPONENTIAL)
174 simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*(std::expm1(temperature_lambdas[i])/std::expm1(1.0));
179 sprintf(errorstr, "eSimTempScale=%d not defined", simtemp->eSimTempScale);
180 gmx_fatal(FARGS, "%s", errorstr);
187 static void _low_check(bool b, const char *s, warninp_t wi)
191 warning_error(wi, s);
195 static void check_nst(const char *desc_nst, int nst,
196 const char *desc_p, int *p,
201 if (*p > 0 && *p % nst != 0)
203 /* Round up to the next multiple of nst */
204 *p = ((*p)/nst + 1)*nst;
205 sprintf(buf, "%s should be a multiple of %s, changing %s to %d\n",
206 desc_p, desc_nst, desc_p, *p);
211 static bool ir_NVE(const t_inputrec *ir)
213 return (EI_MD(ir->eI) && ir->etc == etcNO);
216 static int lcd(int n1, int n2)
221 for (i = 2; (i <= n1 && i <= n2); i++)
223 if (n1 % i == 0 && n2 % i == 0)
232 //! Convert legacy mdp entries to modern ones.
233 static void process_interaction_modifier(int *eintmod)
235 if (*eintmod == eintmodPOTSHIFT_VERLET_UNSUPPORTED)
237 *eintmod = eintmodPOTSHIFT;
241 void check_ir(const char *mdparin, t_inputrec *ir, t_gromppopts *opts,
243 /* Check internal consistency.
244 * NOTE: index groups are not set here yet, don't check things
245 * like temperature coupling group options here, but in triple_check
248 /* Strange macro: first one fills the err_buf, and then one can check
249 * the condition, which will print the message and increase the error
252 #define CHECK(b) _low_check(b, err_buf, wi)
253 char err_buf[256], warn_buf[STRLEN];
256 t_lambda *fep = ir->fepvals;
257 t_expanded *expand = ir->expandedvals;
259 set_warning_line(wi, mdparin, -1);
261 if (ir->coulombtype == eelRF_NEC_UNSUPPORTED)
263 sprintf(warn_buf, "%s electrostatics is no longer supported",
264 eel_names[eelRF_NEC_UNSUPPORTED]);
265 warning_error(wi, warn_buf);
268 /* BASIC CUT-OFF STUFF */
269 if (ir->rcoulomb < 0)
271 warning_error(wi, "rcoulomb should be >= 0");
275 warning_error(wi, "rvdw should be >= 0");
278 !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0))
280 warning_error(wi, "rlist should be >= 0");
282 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.)");
283 CHECK(ir->nstlist < 0);
285 process_interaction_modifier(&ir->coulomb_modifier);
286 process_interaction_modifier(&ir->vdw_modifier);
288 if (ir->cutoff_scheme == ecutsGROUP)
291 "The group cutoff scheme has been removed since GROMACS 2020. "
292 "Please use the Verlet cutoff scheme.");
294 if (ir->cutoff_scheme == ecutsVERLET)
298 /* Normal Verlet type neighbor-list, currently only limited feature support */
299 if (inputrec2nboundeddim(ir) < 3)
301 warning_error(wi, "With Verlet lists only full pbc or pbc=xy with walls is supported");
304 // We don't (yet) have general Verlet kernels for rcoulomb!=rvdw
305 if (ir->rcoulomb != ir->rvdw)
307 // Since we have PME coulomb + LJ cut-off kernels with rcoulomb>rvdw
308 // for PME load balancing, we can support this exception.
309 bool bUsesPmeTwinRangeKernel = (EEL_PME_EWALD(ir->coulombtype) &&
310 ir->vdwtype == evdwCUT &&
311 ir->rcoulomb > ir->rvdw);
312 if (!bUsesPmeTwinRangeKernel)
314 warning_error(wi, "With Verlet lists rcoulomb!=rvdw is not supported (except for rcoulomb>rvdw with PME electrostatics)");
318 if (ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwSWITCH)
320 if (ir->vdw_modifier == eintmodNONE ||
321 ir->vdw_modifier == eintmodPOTSHIFT)
323 ir->vdw_modifier = (ir->vdwtype == evdwSHIFT ? eintmodFORCESWITCH : eintmodPOTSWITCH);
325 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]);
326 warning_note(wi, warn_buf);
328 ir->vdwtype = evdwCUT;
332 sprintf(warn_buf, "Unsupported combination of vdwtype=%s and vdw_modifier=%s", evdw_names[ir->vdwtype], eintmod_names[ir->vdw_modifier]);
333 warning_error(wi, warn_buf);
337 if (!(ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME))
339 warning_error(wi, "With Verlet lists only cut-off and PME LJ interactions are supported");
341 if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) ||
342 EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD))
344 warning_error(wi, "With Verlet lists only cut-off, reaction-field, PME and Ewald electrostatics are supported");
346 if (!(ir->coulomb_modifier == eintmodNONE ||
347 ir->coulomb_modifier == eintmodPOTSHIFT))
349 sprintf(warn_buf, "coulomb_modifier=%s is not supported", eintmod_names[ir->coulomb_modifier]);
350 warning_error(wi, warn_buf);
353 if (EEL_USER(ir->coulombtype))
355 sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme", eel_names[ir->coulombtype]);
356 warning_error(wi, warn_buf);
359 if (ir->nstlist <= 0)
361 warning_error(wi, "With Verlet lists nstlist should be larger than 0");
364 if (ir->nstlist < 10)
366 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.");
369 rc_max = std::max(ir->rvdw, ir->rcoulomb);
373 /* With TPI we set the pairlist cut-off later using the radius of the insterted molecule */
374 ir->verletbuf_tol = 0;
377 else if (ir->verletbuf_tol <= 0)
379 if (ir->verletbuf_tol == 0)
381 warning_error(wi, "Can not have Verlet buffer tolerance of exactly 0");
384 if (ir->rlist < rc_max)
386 warning_error(wi, "With verlet lists rlist can not be smaller than rvdw or rcoulomb");
389 if (ir->rlist == rc_max && ir->nstlist > 1)
391 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.");
396 if (ir->rlist > rc_max)
398 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.");
401 if (ir->nstlist == 1)
403 /* No buffer required */
408 if (EI_DYNAMICS(ir->eI))
410 if (inputrec2nboundeddim(ir) < 3)
412 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.");
414 /* Set rlist temporarily so we can continue processing */
419 /* Set the buffer to 5% of the cut-off */
420 ir->rlist = (1.0 + verlet_buffer_ratio_nodynamics)*rc_max;
426 /* GENERAL INTEGRATOR STUFF */
429 if (ir->etc != etcNO)
431 if (EI_RANDOM(ir->eI))
433 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]);
437 sprintf(warn_buf, "Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to %s.", etcoupl_names[ir->etc], ei_names[ir->eI]);
439 warning_note(wi, warn_buf);
443 if (ir->eI == eiVVAK)
445 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]);
446 warning_note(wi, warn_buf);
448 if (!EI_DYNAMICS(ir->eI))
450 if (ir->epc != epcNO)
452 sprintf(warn_buf, "Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.", epcoupl_names[ir->epc], ei_names[ir->eI]);
453 warning_note(wi, warn_buf);
457 if (EI_DYNAMICS(ir->eI))
459 if (ir->nstcalcenergy < 0)
461 ir->nstcalcenergy = ir_optimal_nstcalcenergy(ir);
462 if (ir->nstenergy != 0 && ir->nstenergy < ir->nstcalcenergy)
464 /* nstcalcenergy larger than nstener does not make sense.
465 * We ideally want nstcalcenergy=nstener.
469 ir->nstcalcenergy = lcd(ir->nstenergy, ir->nstlist);
473 ir->nstcalcenergy = ir->nstenergy;
477 else if ( (ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy) ||
478 (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
479 (ir->nstcalcenergy > ir->fepvals->nstdhdl) ) )
482 const char *nsten = "nstenergy";
483 const char *nstdh = "nstdhdl";
484 const char *min_name = nsten;
485 int min_nst = ir->nstenergy;
487 /* find the smallest of ( nstenergy, nstdhdl ) */
488 if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
489 (ir->nstenergy == 0 || ir->fepvals->nstdhdl < ir->nstenergy))
491 min_nst = ir->fepvals->nstdhdl;
494 /* If the user sets nstenergy small, we should respect that */
496 "Setting nstcalcenergy (%d) equal to %s (%d)",
497 ir->nstcalcenergy, min_name, min_nst);
498 warning_note(wi, warn_buf);
499 ir->nstcalcenergy = min_nst;
502 if (ir->epc != epcNO)
504 if (ir->nstpcouple < 0)
506 ir->nstpcouple = ir_optimal_nstpcouple(ir);
510 if (ir->nstcalcenergy > 0)
512 if (ir->efep != efepNO)
514 /* nstdhdl should be a multiple of nstcalcenergy */
515 check_nst("nstcalcenergy", ir->nstcalcenergy,
516 "nstdhdl", &ir->fepvals->nstdhdl, wi);
520 /* nstexpanded should be a multiple of nstcalcenergy */
521 check_nst("nstcalcenergy", ir->nstcalcenergy,
522 "nstexpanded", &ir->expandedvals->nstexpanded, wi);
524 /* for storing exact averages nstenergy should be
525 * a multiple of nstcalcenergy
527 check_nst("nstcalcenergy", ir->nstcalcenergy,
528 "nstenergy", &ir->nstenergy, wi);
532 if (ir->nsteps == 0 && !ir->bContinuation)
534 warning_note(wi, "For a correct single-point energy evaluation with nsteps = 0, use continuation = yes to avoid constraining the input coordinates.");
538 if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
539 ir->bContinuation && ir->ld_seed != -1)
541 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)");
547 sprintf(err_buf, "TPI only works with pbc = %s", epbc_names[epbcXYZ]);
548 CHECK(ir->ePBC != epbcXYZ);
549 sprintf(err_buf, "with TPI nstlist should be larger than zero");
550 CHECK(ir->nstlist <= 0);
551 sprintf(err_buf, "TPI does not work with full electrostatics other than PME");
552 CHECK(EEL_FULL(ir->coulombtype) && !EEL_PME(ir->coulombtype));
556 if ( (opts->nshake > 0) && (opts->bMorse) )
559 "Using morse bond-potentials while constraining bonds is useless");
560 warning(wi, warn_buf);
563 if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
564 ir->bContinuation && ir->ld_seed != -1)
566 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)");
568 /* verify simulated tempering options */
572 bool bAllTempZero = TRUE;
573 for (i = 0; i < fep->n_lambda; i++)
575 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]);
576 CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
577 if (fep->all_lambda[efptTEMPERATURE][i] > 0)
579 bAllTempZero = FALSE;
582 sprintf(err_buf, "if simulated tempering is on, temperature-lambdas may not be all zero");
583 CHECK(bAllTempZero == TRUE);
585 sprintf(err_buf, "Simulated tempering is currently only compatible with md-vv");
586 CHECK(ir->eI != eiVV);
588 /* check compatability of the temperature coupling with simulated tempering */
590 if (ir->etc == etcNOSEHOOVER)
592 sprintf(warn_buf, "Nose-Hoover based temperature control such as [%s] my not be entirelyconsistent with simulated tempering", etcoupl_names[ir->etc]);
593 warning_note(wi, warn_buf);
596 /* check that the temperatures make sense */
598 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);
599 CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low);
601 sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_high);
602 CHECK(ir->simtempvals->simtemp_high <= 0);
604 sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_low);
605 CHECK(ir->simtempvals->simtemp_low <= 0);
608 /* verify free energy options */
610 if (ir->efep != efepNO)
613 sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2",
615 CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2);
617 sprintf(err_buf, "The soft-core sc-r-power is %d and can only be 6 or 48",
618 static_cast<int>(fep->sc_r_power));
619 CHECK(fep->sc_alpha != 0 && fep->sc_r_power != 6.0 && fep->sc_r_power != 48.0);
621 sprintf(err_buf, "Can't use positive delta-lambda (%g) if initial state/lambda does not start at zero", fep->delta_lambda);
622 CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0)));
624 sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations", fep->delta_lambda);
625 CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
627 sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)");
628 CHECK(!(EI_VV(ir->eI)) && (ir->efep == efepEXPANDED));
630 sprintf(err_buf, "Free-energy not implemented for Ewald");
631 CHECK(ir->coulombtype == eelEWALD);
633 /* check validty of lambda inputs */
634 if (fep->n_lambda == 0)
636 /* Clear output in case of no states:*/
637 sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state);
638 CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0));
642 sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d", fep->init_fep_state, fep->n_lambda-1);
643 CHECK((fep->init_fep_state >= fep->n_lambda));
646 sprintf(err_buf, "Lambda state must be set, either with init-lambda-state or with init-lambda");
647 CHECK((fep->init_fep_state < 0) && (fep->init_lambda < 0));
649 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",
650 fep->init_lambda, fep->init_fep_state);
651 CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
655 if ((fep->init_lambda >= 0) && (fep->delta_lambda == 0))
659 for (i = 0; i < efptNR; i++)
661 if (fep->separate_dvdl[i])
666 if (n_lambda_terms > 1)
668 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.");
669 warning(wi, warn_buf);
672 if (n_lambda_terms < 2 && fep->n_lambda > 0)
675 "init-lambda is deprecated for setting lambda state (except for slow growth). Use init-lambda-state instead.");
679 for (j = 0; j < efptNR; j++)
681 for (i = 0; i < fep->n_lambda; i++)
683 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]);
684 CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
688 if ((fep->sc_alpha > 0) && (!fep->bScCoul))
690 for (i = 0; i < fep->n_lambda; i++)
692 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],
693 fep->all_lambda[efptCOUL][i]);
694 CHECK((fep->sc_alpha > 0) &&
695 (((fep->all_lambda[efptCOUL][i] > 0.0) &&
696 (fep->all_lambda[efptCOUL][i] < 1.0)) &&
697 ((fep->all_lambda[efptVDW][i] > 0.0) &&
698 (fep->all_lambda[efptVDW][i] < 1.0))));
702 if ((fep->bScCoul) && (EEL_PME(ir->coulombtype)))
704 real sigma, lambda, r_sc;
707 /* Maximum estimate for A and B charges equal with lambda power 1 */
709 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);
710 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.",
712 sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
713 warning_note(wi, warn_buf);
716 /* Free Energy Checks -- In an ideal world, slow growth and FEP would
717 be treated differently, but that's the next step */
719 for (i = 0; i < efptNR; i++)
721 for (j = 0; j < fep->n_lambda; j++)
723 sprintf(err_buf, "%s[%d] must be between 0 and 1", efpt_names[i], j);
724 CHECK((fep->all_lambda[i][j] < 0) || (fep->all_lambda[i][j] > 1));
729 if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
733 /* checking equilibration of weights inputs for validity */
735 sprintf(err_buf, "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal to %s",
736 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
737 CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
739 sprintf(err_buf, "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to %s",
740 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
741 CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
743 sprintf(err_buf, "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
744 expand->equil_steps, elmceq_names[elmceqSTEPS]);
745 CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
747 sprintf(err_buf, "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
748 expand->equil_samples, elmceq_names[elmceqWLDELTA]);
749 CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
751 sprintf(err_buf, "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
752 expand->equil_ratio, elmceq_names[elmceqRATIO]);
753 CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
755 sprintf(err_buf, "weight-equil-number-all-lambda (%d) must be a positive integer if lmc-weights-equil=%s",
756 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
757 CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
759 sprintf(err_buf, "weight-equil-number-samples (%d) must be a positive integer if lmc-weights-equil=%s",
760 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
761 CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
763 sprintf(err_buf, "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
764 expand->equil_steps, elmceq_names[elmceqSTEPS]);
765 CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
767 sprintf(err_buf, "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
768 expand->equil_wl_delta, elmceq_names[elmceqWLDELTA]);
769 CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
771 sprintf(err_buf, "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
772 expand->equil_ratio, elmceq_names[elmceqRATIO]);
773 CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
775 sprintf(err_buf, "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
776 elmceq_names[elmceqWLDELTA], elamstats_names[elamstatsWL], elamstats_names[elamstatsWWL]);
777 CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
779 sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
780 CHECK((expand->lmc_repeats <= 0));
781 sprintf(err_buf, "minimum-var-min (%d) must be greater than 0", expand->minvarmin);
782 CHECK((expand->minvarmin <= 0));
783 sprintf(err_buf, "weight-c-range (%d) must be greater or equal to 0", expand->c_range);
784 CHECK((expand->c_range < 0));
785 sprintf(err_buf, "init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != 'no'",
786 fep->init_fep_state, expand->lmc_forced_nstart);
787 CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0) && (expand->elmcmove != elmcmoveNO));
788 sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
789 CHECK((expand->lmc_forced_nstart < 0));
790 sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)", fep->init_fep_state);
791 CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda));
793 sprintf(err_buf, "init-wl-delta (%f) must be greater than or equal to 0", expand->init_wl_delta);
794 CHECK((expand->init_wl_delta < 0));
795 sprintf(err_buf, "wl-ratio (%f) must be between 0 and 1", expand->wl_ratio);
796 CHECK((expand->wl_ratio <= 0) || (expand->wl_ratio >= 1));
797 sprintf(err_buf, "wl-scale (%f) must be between 0 and 1", expand->wl_scale);
798 CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1));
800 /* if there is no temperature control, we need to specify an MC temperature */
801 if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO) && (expand->mc_temp <= 0.0))
803 sprintf(err_buf, "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set to a positive number");
804 warning_error(wi, err_buf);
806 if (expand->nstTij > 0)
808 sprintf(err_buf, "nstlog must be non-zero");
809 CHECK(ir->nstlog == 0);
810 // Avoid modulus by zero in the case that already triggered an error exit.
813 sprintf(err_buf, "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
814 expand->nstTij, ir->nstlog);
815 CHECK((expand->nstTij % ir->nstlog) != 0);
821 sprintf(err_buf, "walls only work with pbc=%s", epbc_names[epbcXY]);
822 CHECK(ir->nwall && ir->ePBC != epbcXY);
825 if (ir->ePBC != epbcXYZ && ir->nwall != 2)
827 if (ir->ePBC == epbcNONE)
829 if (ir->epc != epcNO)
831 warning(wi, "Turning off pressure coupling for vacuum system");
837 sprintf(err_buf, "Can not have pressure coupling with pbc=%s",
838 epbc_names[ir->ePBC]);
839 CHECK(ir->epc != epcNO);
841 sprintf(err_buf, "Can not have Ewald with pbc=%s", epbc_names[ir->ePBC]);
842 CHECK(EEL_FULL(ir->coulombtype));
844 sprintf(err_buf, "Can not have dispersion correction with pbc=%s",
845 epbc_names[ir->ePBC]);
846 CHECK(ir->eDispCorr != edispcNO);
849 if (ir->rlist == 0.0)
851 sprintf(err_buf, "can only have neighborlist cut-off zero (=infinite)\n"
852 "with coulombtype = %s or coulombtype = %s\n"
853 "without periodic boundary conditions (pbc = %s) and\n"
854 "rcoulomb and rvdw set to zero",
855 eel_names[eelCUT], eel_names[eelUSER], epbc_names[epbcNONE]);
856 CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER)) ||
857 (ir->ePBC != epbcNONE) ||
858 (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0));
862 warning_note(wi, "Simulating without cut-offs can be (slightly) faster with nstlist=0, nstype=simple and only one MPI rank");
867 if (ir->nstcomm == 0)
869 // TODO Change this behaviour. There should be exactly one way
870 // to turn off an algorithm.
871 ir->comm_mode = ecmNO;
873 if (ir->comm_mode != ecmNO)
877 // TODO Such input was once valid. Now that we've been
878 // helpful for a few years, we should reject such input,
879 // lest we have to support every historical decision
881 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");
882 ir->nstcomm = abs(ir->nstcomm);
885 if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy)
887 warning_note(wi, "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting nstcomm to nstcalcenergy");
888 ir->nstcomm = ir->nstcalcenergy;
891 if (ir->comm_mode == ecmANGULAR)
893 sprintf(err_buf, "Can not remove the rotation around the center of mass with periodic molecules");
894 CHECK(ir->bPeriodicMols);
895 if (ir->ePBC != epbcNONE)
897 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.");
902 if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->ePBC == epbcNONE && ir->comm_mode != ecmANGULAR)
904 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]);
905 warning_note(wi, warn_buf);
908 /* TEMPERATURE COUPLING */
909 if (ir->etc == etcYES)
911 ir->etc = etcBERENDSEN;
912 warning_note(wi, "Old option for temperature coupling given: "
913 "changing \"yes\" to \"Berendsen\"\n");
916 if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
918 if (ir->opts.nhchainlength < 1)
920 sprintf(warn_buf, "number of Nose-Hoover chains (currently %d) cannot be less than 1,reset to 1\n", ir->opts.nhchainlength);
921 ir->opts.nhchainlength = 1;
922 warning(wi, warn_buf);
925 if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
927 warning_note(wi, "leapfrog does not yet support Nose-Hoover chains, nhchainlength reset to 1");
928 ir->opts.nhchainlength = 1;
933 ir->opts.nhchainlength = 0;
936 if (ir->eI == eiVVAK)
938 sprintf(err_buf, "%s implemented primarily for validation, and requires nsttcouple = 1 and nstpcouple = 1.",
940 CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1));
943 if (ETC_ANDERSEN(ir->etc))
945 sprintf(err_buf, "%s temperature control not supported for integrator %s.", etcoupl_names[ir->etc], ei_names[ir->eI]);
946 CHECK(!(EI_VV(ir->eI)));
948 if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
950 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]);
951 warning_note(wi, warn_buf);
954 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]);
955 CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
958 if (ir->etc == etcBERENDSEN)
960 sprintf(warn_buf, "The %s thermostat does not generate the correct kinetic energy distribution. You might want to consider using the %s thermostat.",
961 ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
962 warning_note(wi, warn_buf);
965 if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc))
966 && ir->epc == epcBERENDSEN)
968 sprintf(warn_buf, "Using Berendsen pressure coupling invalidates the "
969 "true ensemble for the thermostat");
970 warning(wi, warn_buf);
973 /* PRESSURE COUPLING */
974 if (ir->epc == epcISOTROPIC)
976 ir->epc = epcBERENDSEN;
977 warning_note(wi, "Old option for pressure coupling given: "
978 "changing \"Isotropic\" to \"Berendsen\"\n");
981 if (ir->epc != epcNO)
983 dt_pcoupl = ir->nstpcouple*ir->delta_t;
985 sprintf(err_buf, "tau-p must be > 0 instead of %g\n", ir->tau_p);
986 CHECK(ir->tau_p <= 0);
988 if (ir->tau_p/dt_pcoupl < pcouple_min_integration_steps(ir->epc) - 10*GMX_REAL_EPS)
990 sprintf(warn_buf, "For proper integration of the %s barostat, tau-p (%g) should be at least %d times larger than nstpcouple*dt (%g)",
991 EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl);
992 warning(wi, warn_buf);
995 sprintf(err_buf, "compressibility must be > 0 when using pressure"
996 " coupling %s\n", EPCOUPLTYPE(ir->epc));
997 CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 ||
998 ir->compress[ZZ][ZZ] < 0 ||
999 (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 &&
1000 ir->compress[ZZ][XX] <= 0 && ir->compress[ZZ][YY] <= 0));
1002 if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
1005 "You are generating velocities so I am assuming you "
1006 "are equilibrating a system. You are using "
1007 "%s pressure coupling, but this can be "
1008 "unstable for equilibration. If your system crashes, try "
1009 "equilibrating first with Berendsen pressure coupling. If "
1010 "you are not equilibrating the system, you can probably "
1011 "ignore this warning.",
1012 epcoupl_names[ir->epc]);
1013 warning(wi, warn_buf);
1019 if (ir->epc > epcNO)
1021 if ((ir->epc != epcBERENDSEN) && (ir->epc != epcMTTK))
1023 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.");
1029 if (ir->epc == epcMTTK)
1031 warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
1035 /* ELECTROSTATICS */
1036 /* More checks are in triple check (grompp.c) */
1038 if (ir->coulombtype == eelSWITCH)
1040 sprintf(warn_buf, "coulombtype = %s is only for testing purposes and can lead to serious "
1041 "artifacts, advice: use coulombtype = %s",
1042 eel_names[ir->coulombtype],
1043 eel_names[eelRF_ZERO]);
1044 warning(wi, warn_buf);
1047 if (EEL_RF(ir->coulombtype) && ir->epsilon_rf == 1 && ir->epsilon_r != 1)
1049 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);
1050 warning(wi, warn_buf);
1051 ir->epsilon_rf = ir->epsilon_r;
1052 ir->epsilon_r = 1.0;
1055 if (ir->epsilon_r == 0)
1058 "It is pointless to use long-range electrostatics with infinite relative permittivity."
1059 "Since you are effectively turning of electrostatics, a plain cutoff will be much faster.");
1060 CHECK(EEL_FULL(ir->coulombtype));
1063 if (getenv("GMX_DO_GALACTIC_DYNAMICS") == nullptr)
1065 sprintf(err_buf, "epsilon-r must be >= 0 instead of %g\n", ir->epsilon_r);
1066 CHECK(ir->epsilon_r < 0);
1069 if (EEL_RF(ir->coulombtype))
1071 /* reaction field (at the cut-off) */
1073 if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0)
1075 sprintf(warn_buf, "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0",
1076 eel_names[ir->coulombtype]);
1077 warning(wi, warn_buf);
1078 ir->epsilon_rf = 0.0;
1081 sprintf(err_buf, "epsilon-rf must be >= epsilon-r");
1082 CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) ||
1083 (ir->epsilon_r == 0));
1084 if (ir->epsilon_rf == ir->epsilon_r)
1086 sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense",
1087 eel_names[ir->coulombtype]);
1088 warning(wi, warn_buf);
1091 /* Allow rlist>rcoulomb for tabulated long range stuff. This just
1092 * means the interaction is zero outside rcoulomb, but it helps to
1093 * provide accurate energy conservation.
1095 if (ir_coulomb_might_be_zero_at_cutoff(ir))
1097 if (ir_coulomb_switched(ir))
1100 "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the potential modifier options!",
1101 eel_names[ir->coulombtype]);
1102 CHECK(ir->rcoulomb_switch >= ir->rcoulomb);
1106 if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT)
1109 "Explicit switch/shift coulomb interactions cannot be used in combination with a secondary coulomb-modifier.");
1110 CHECK( ir->coulomb_modifier != eintmodNONE);
1112 if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1115 "Explicit switch/shift vdw interactions cannot be used in combination with a secondary vdw-modifier.");
1116 CHECK( ir->vdw_modifier != eintmodNONE);
1119 if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT ||
1120 ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1123 "The switch/shift interaction settings are just for compatibility; you will get better "
1124 "performance from applying potential modifiers to your interactions!\n");
1125 warning_note(wi, warn_buf);
1128 if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH)
1130 if (ir->rcoulomb_switch/ir->rcoulomb < 0.9499)
1132 real percentage = 100*(ir->rcoulomb-ir->rcoulomb_switch)/ir->rcoulomb;
1133 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.",
1134 percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol);
1135 warning(wi, warn_buf);
1139 if (ir->vdwtype == evdwSWITCH || ir->vdw_modifier == eintmodPOTSWITCH)
1141 if (ir->rvdw_switch == 0)
1143 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.");
1144 warning(wi, warn_buf);
1148 if (EEL_FULL(ir->coulombtype))
1150 if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER ||
1151 ir->coulombtype == eelPMEUSERSWITCH)
1153 sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist",
1154 eel_names[ir->coulombtype]);
1155 CHECK(ir->rcoulomb > ir->rlist);
1159 if (EEL_PME(ir->coulombtype) || EVDW_PME(ir->vdwtype))
1161 // TODO: Move these checks into the ewald module with the options class
1163 int orderMax = (ir->coulombtype == eelP3M_AD ? 8 : 12);
1165 if (ir->pme_order < orderMin || ir->pme_order > orderMax)
1167 sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d", eel_names[ir->coulombtype], orderMin, orderMax);
1168 warning_error(wi, warn_buf);
1172 if (ir->nwall == 2 && EEL_FULL(ir->coulombtype))
1174 if (ir->ewald_geometry == eewg3D)
1176 sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s",
1177 epbc_names[ir->ePBC], eewg_names[eewg3DC]);
1178 warning(wi, warn_buf);
1180 /* This check avoids extra pbc coding for exclusion corrections */
1181 sprintf(err_buf, "wall-ewald-zfac should be >= 2");
1182 CHECK(ir->wall_ewald_zfac < 2);
1184 if ((ir->ewald_geometry == eewg3DC) && (ir->ePBC != epbcXY) &&
1185 EEL_FULL(ir->coulombtype))
1187 sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s",
1188 eel_names[ir->coulombtype], eewg_names[eewg3DC], epbc_names[epbcXY]);
1189 warning(wi, warn_buf);
1191 if ((ir->epsilon_surface != 0) && EEL_FULL(ir->coulombtype))
1193 if (ir->cutoff_scheme == ecutsVERLET)
1195 sprintf(warn_buf, "Since molecules/charge groups are broken using the Verlet scheme, you can not use a dipole correction to the %s electrostatics.",
1196 eel_names[ir->coulombtype]);
1197 warning(wi, warn_buf);
1201 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",
1202 eel_names[ir->coulombtype]);
1203 warning_note(wi, warn_buf);
1207 if (ir_vdw_switched(ir))
1209 sprintf(err_buf, "With switched vdw forces or potentials, rvdw-switch must be < rvdw");
1210 CHECK(ir->rvdw_switch >= ir->rvdw);
1212 if (ir->rvdw_switch < 0.5*ir->rvdw)
1214 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.",
1215 ir->rvdw_switch, ir->rvdw);
1216 warning_note(wi, warn_buf);
1220 if (ir->vdwtype == evdwPME)
1222 if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
1224 sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s",
1225 evdw_names[ir->vdwtype],
1226 eintmod_names[eintmodPOTSHIFT],
1227 eintmod_names[eintmodNONE]);
1228 warning_error(wi, err_buf);
1232 if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO)
1234 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.");
1237 if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT)
1240 warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off.");
1243 if (ir->eI == eiLBFGS && ir->nbfgscorr <= 0)
1245 warning(wi, "Using L-BFGS with nbfgscorr<=0 just gets you steepest descent.");
1248 /* IMPLICIT SOLVENT */
1249 if (ir->coulombtype == eelGB_NOTUSED)
1251 sprintf(warn_buf, "Invalid option %s for coulombtype",
1252 eel_names[ir->coulombtype]);
1253 warning_error(wi, warn_buf);
1258 if (ir->cutoff_scheme != ecutsGROUP)
1260 warning_error(wi, "QMMM is currently only supported with cutoff-scheme=group");
1262 if (!EI_DYNAMICS(ir->eI))
1265 sprintf(buf, "QMMM is only supported with dynamics, not with integrator %s", ei_names[ir->eI]);
1266 warning_error(wi, buf);
1272 gmx_fatal(FARGS, "AdResS simulations are no longer supported");
1276 /* interpret a number of doubles from a string and put them in an array,
1277 after allocating space for them.
1278 str = the input string
1279 n = the (pre-allocated) number of doubles read
1280 r = the output array of doubles. */
1281 static void parse_n_real(char *str, int *n, real **r, warninp_t wi)
1283 auto values = gmx::splitString(str);
1287 for (int i = 0; i < *n; i++)
1291 (*r)[i] = gmx::fromString<real>(values[i]);
1293 catch (gmx::GromacsException &)
1295 warning_error(wi, "Invalid value " + values[i] + " in string in mdp file. Expected a real number.");
1301 static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi)
1304 int i, j, max_n_lambda, nweights, nfep[efptNR];
1305 t_lambda *fep = ir->fepvals;
1306 t_expanded *expand = ir->expandedvals;
1307 real **count_fep_lambdas;
1308 bool bOneLambda = TRUE;
1310 snew(count_fep_lambdas, efptNR);
1312 /* FEP input processing */
1313 /* first, identify the number of lambda values for each type.
1314 All that are nonzero must have the same number */
1316 for (i = 0; i < efptNR; i++)
1318 parse_n_real(fep_lambda[i], &(nfep[i]), &(count_fep_lambdas[i]), wi);
1321 /* now, determine the number of components. All must be either zero, or equal. */
1324 for (i = 0; i < efptNR; i++)
1326 if (nfep[i] > max_n_lambda)
1328 max_n_lambda = nfep[i]; /* here's a nonzero one. All of them
1329 must have the same number if its not zero.*/
1334 for (i = 0; i < efptNR; i++)
1338 ir->fepvals->separate_dvdl[i] = FALSE;
1340 else if (nfep[i] == max_n_lambda)
1342 if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute the derivative with
1343 respect to the temperature currently */
1345 ir->fepvals->separate_dvdl[i] = TRUE;
1350 gmx_fatal(FARGS, "Number of lambdas (%d) for FEP type %s not equal to number of other types (%d)",
1351 nfep[i], efpt_names[i], max_n_lambda);
1354 /* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
1355 ir->fepvals->separate_dvdl[efptTEMPERATURE] = FALSE;
1357 /* the number of lambdas is the number we've read in, which is either zero
1358 or the same for all */
1359 fep->n_lambda = max_n_lambda;
1361 /* allocate space for the array of lambda values */
1362 snew(fep->all_lambda, efptNR);
1363 /* if init_lambda is defined, we need to set lambda */
1364 if ((fep->init_lambda > 0) && (fep->n_lambda == 0))
1366 ir->fepvals->separate_dvdl[efptFEP] = TRUE;
1368 /* otherwise allocate the space for all of the lambdas, and transfer the data */
1369 for (i = 0; i < efptNR; i++)
1371 snew(fep->all_lambda[i], fep->n_lambda);
1372 if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays
1375 for (j = 0; j < fep->n_lambda; j++)
1377 fep->all_lambda[i][j] = static_cast<double>(count_fep_lambdas[i][j]);
1379 sfree(count_fep_lambdas[i]);
1382 sfree(count_fep_lambdas);
1384 /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for internal
1385 bookkeeping -- for now, init_lambda */
1387 if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
1389 for (i = 0; i < fep->n_lambda; i++)
1391 fep->all_lambda[efptFEP][i] = fep->init_lambda;
1395 /* check to see if only a single component lambda is defined, and soft core is defined.
1396 In this case, turn on coulomb soft core */
1398 if (max_n_lambda == 0)
1404 for (i = 0; i < efptNR; i++)
1406 if ((nfep[i] != 0) && (i != efptFEP))
1412 if ((bOneLambda) && (fep->sc_alpha > 0))
1414 fep->bScCoul = TRUE;
1417 /* Fill in the others with the efptFEP if they are not explicitly
1418 specified (i.e. nfep[i] == 0). This means if fep is not defined,
1419 they are all zero. */
1421 for (i = 0; i < efptNR; i++)
1423 if ((nfep[i] == 0) && (i != efptFEP))
1425 for (j = 0; j < fep->n_lambda; j++)
1427 fep->all_lambda[i][j] = fep->all_lambda[efptFEP][j];
1433 /* make it easier if sc_r_power = 48 by increasing it to the 4th power, to be in the right scale. */
1434 if (fep->sc_r_power == 48)
1436 if (fep->sc_alpha > 0.1)
1438 gmx_fatal(FARGS, "sc_alpha (%f) for sc_r_power = 48 should usually be between 0.001 and 0.004", fep->sc_alpha);
1442 /* now read in the weights */
1443 parse_n_real(weights, &nweights, &(expand->init_lambda_weights), wi);
1446 snew(expand->init_lambda_weights, fep->n_lambda); /* initialize to zero */
1448 else if (nweights != fep->n_lambda)
1450 gmx_fatal(FARGS, "Number of weights (%d) is not equal to number of lambda values (%d)",
1451 nweights, fep->n_lambda);
1453 if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
1455 expand->nstexpanded = fep->nstdhdl;
1456 /* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
1461 static void do_simtemp_params(t_inputrec *ir)
1464 snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda);
1465 GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]);
1469 convertYesNos(warninp_t /*wi*/, gmx::ArrayRef<const std::string> inputs, const char * /*name*/, gmx_bool *outputs)
1472 for (const auto &input : inputs)
1474 outputs[i] = gmx::equalCaseInsensitive(input, "Y", 1);
1479 template <typename T> void
1480 convertInts(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, T *outputs)
1483 for (const auto &input : inputs)
1487 outputs[i] = gmx::fromStdString<T>(input);
1489 catch (gmx::GromacsException &)
1491 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of integers separated by spaces.",
1493 warning_error(wi, message);
1500 convertReals(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, real *outputs)
1503 for (const auto &input : inputs)
1507 outputs[i] = gmx::fromString<real>(input);
1509 catch (gmx::GromacsException &)
1511 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1513 warning_error(wi, message);
1520 convertRvecs(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, rvec *outputs)
1523 for (const auto &input : inputs)
1527 outputs[i][d] = gmx::fromString<real>(input);
1529 catch (gmx::GromacsException &)
1531 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1533 warning_error(wi, message);
1544 static void do_wall_params(t_inputrec *ir,
1545 char *wall_atomtype, char *wall_density,
1549 opts->wall_atomtype[0] = nullptr;
1550 opts->wall_atomtype[1] = nullptr;
1552 ir->wall_atomtype[0] = -1;
1553 ir->wall_atomtype[1] = -1;
1554 ir->wall_density[0] = 0;
1555 ir->wall_density[1] = 0;
1559 auto wallAtomTypes = gmx::splitString(wall_atomtype);
1560 if (wallAtomTypes.size() != size_t(ir->nwall))
1562 gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu",
1563 ir->nwall, wallAtomTypes.size());
1565 for (int i = 0; i < ir->nwall; i++)
1567 opts->wall_atomtype[i] = gmx_strdup(wallAtomTypes[i].c_str());
1570 if (ir->wall_type == ewt93 || ir->wall_type == ewt104)
1572 auto wallDensity = gmx::splitString(wall_density);
1573 if (wallDensity.size() != size_t(ir->nwall))
1575 gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall, wallDensity.size());
1577 convertReals(wi, wallDensity, "wall-density", ir->wall_density);
1578 for (int i = 0; i < ir->nwall; i++)
1580 if (ir->wall_density[i] <= 0)
1582 gmx_fatal(FARGS, "wall-density[%d] = %f\n", i, ir->wall_density[i]);
1589 static void add_wall_energrps(SimulationGroups *groups, int nwall, t_symtab *symtab)
1593 AtomGroupIndices *grps = &(groups->groups[SimulationAtomGroupType::EnergyOutput]);
1594 for (int i = 0; i < nwall; i++)
1596 groups->groupNames.emplace_back(
1599 gmx::formatString("wall%d", i).c_str()));
1600 grps->emplace_back(groups->groupNames.size() - 1);
1605 static void read_expandedparams(std::vector<t_inpfile> *inp,
1606 t_expanded *expand, warninp_t wi)
1608 /* read expanded ensemble parameters */
1609 printStringNewline(inp, "expanded ensemble variables");
1610 expand->nstexpanded = get_eint(inp, "nstexpanded", -1, wi);
1611 expand->elamstats = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
1612 expand->elmcmove = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
1613 expand->elmceq = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
1614 expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
1615 expand->equil_samples = get_eint(inp, "weight-equil-number-samples", -1, wi);
1616 expand->equil_steps = get_eint(inp, "weight-equil-number-steps", -1, wi);
1617 expand->equil_wl_delta = get_ereal(inp, "weight-equil-wl-delta", -1, wi);
1618 expand->equil_ratio = get_ereal(inp, "weight-equil-count-ratio", -1, wi);
1619 printStringNewline(inp, "Seed for Monte Carlo in lambda space");
1620 expand->lmc_seed = get_eint(inp, "lmc-seed", -1, wi);
1621 expand->mc_temp = get_ereal(inp, "mc-temperature", -1, wi);
1622 expand->lmc_repeats = get_eint(inp, "lmc-repeats", 1, wi);
1623 expand->gibbsdeltalam = get_eint(inp, "lmc-gibbsdelta", -1, wi);
1624 expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi);
1625 expand->bSymmetrizedTMatrix = (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0);
1626 expand->nstTij = get_eint(inp, "nst-transition-matrix", -1, wi);
1627 expand->minvarmin = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
1628 expand->c_range = get_eint(inp, "weight-c-range", 0, wi); /* default is just C=0 */
1629 expand->wl_scale = get_ereal(inp, "wl-scale", 0.8, wi);
1630 expand->wl_ratio = get_ereal(inp, "wl-ratio", 0.8, wi);
1631 expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi);
1632 expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
1635 /*! \brief Return whether an end state with the given coupling-lambda
1636 * value describes fully-interacting VDW.
1638 * \param[in] couple_lambda_value Enumeration ecouplam value describing the end state
1639 * \return Whether VDW is on (i.e. the user chose vdw or vdw-q in the .mdp file)
1641 static bool couple_lambda_has_vdw_on(int couple_lambda_value)
1643 return (couple_lambda_value == ecouplamVDW ||
1644 couple_lambda_value == ecouplamVDWQ);
1650 class MdpErrorHandler : public gmx::IKeyValueTreeErrorHandler
1653 explicit MdpErrorHandler(warninp_t wi)
1654 : wi_(wi), mapping_(nullptr)
1658 void setBackMapping(const gmx::IKeyValueTreeBackMapping &mapping)
1660 mapping_ = &mapping;
1663 bool onError(gmx::UserInputError *ex, const gmx::KeyValueTreePath &context) override
1665 ex->prependContext(gmx::formatString("Error in mdp option \"%s\":",
1666 getOptionName(context).c_str()));
1667 std::string message = gmx::formatExceptionMessageToString(*ex);
1668 warning_error(wi_, message.c_str());
1673 std::string getOptionName(const gmx::KeyValueTreePath &context)
1675 if (mapping_ != nullptr)
1677 gmx::KeyValueTreePath path = mapping_->originalPath(context);
1678 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
1681 GMX_ASSERT(context.size() == 1, "Inconsistent context for mdp option parsing");
1686 const gmx::IKeyValueTreeBackMapping *mapping_;
1691 void get_ir(const char *mdparin, const char *mdparout,
1692 gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
1693 WriteMdpHeader writeMdpHeader, warninp_t wi)
1696 double dumdub[2][6];
1698 char warn_buf[STRLEN];
1699 t_lambda *fep = ir->fepvals;
1700 t_expanded *expand = ir->expandedvals;
1702 const char *no_names[] = { "no", nullptr };
1704 init_inputrec_strings();
1705 gmx::TextInputFile stream(mdparin);
1706 std::vector<t_inpfile> inp = read_inpfile(&stream, mdparin, wi);
1708 snew(dumstr[0], STRLEN);
1709 snew(dumstr[1], STRLEN);
1711 if (-1 == search_einp(inp, "cutoff-scheme"))
1714 "%s did not specify a value for the .mdp option "
1715 "\"cutoff-scheme\". As of GROMACS 2020, the Verlet scheme "
1716 "is the only cutoff scheme supported. This may affect your "
1717 "simulation if you are using an old mdp file that assumes use "
1718 "of the (removed) group cutoff scheme.", mdparin);
1719 warning_note(wi, warn_buf);
1722 /* ignore the following deprecated commands */
1723 replace_inp_entry(inp, "title", nullptr);
1724 replace_inp_entry(inp, "cpp", nullptr);
1725 replace_inp_entry(inp, "domain-decomposition", nullptr);
1726 replace_inp_entry(inp, "andersen-seed", nullptr);
1727 replace_inp_entry(inp, "dihre", nullptr);
1728 replace_inp_entry(inp, "dihre-fc", nullptr);
1729 replace_inp_entry(inp, "dihre-tau", nullptr);
1730 replace_inp_entry(inp, "nstdihreout", nullptr);
1731 replace_inp_entry(inp, "nstcheckpoint", nullptr);
1732 replace_inp_entry(inp, "optimize-fft", nullptr);
1733 replace_inp_entry(inp, "adress_type", nullptr);
1734 replace_inp_entry(inp, "adress_const_wf", nullptr);
1735 replace_inp_entry(inp, "adress_ex_width", nullptr);
1736 replace_inp_entry(inp, "adress_hy_width", nullptr);
1737 replace_inp_entry(inp, "adress_ex_forcecap", nullptr);
1738 replace_inp_entry(inp, "adress_interface_correction", nullptr);
1739 replace_inp_entry(inp, "adress_site", nullptr);
1740 replace_inp_entry(inp, "adress_reference_coords", nullptr);
1741 replace_inp_entry(inp, "adress_tf_grp_names", nullptr);
1742 replace_inp_entry(inp, "adress_cg_grp_names", nullptr);
1743 replace_inp_entry(inp, "adress_do_hybridpairs", nullptr);
1744 replace_inp_entry(inp, "rlistlong", nullptr);
1745 replace_inp_entry(inp, "nstcalclr", nullptr);
1746 replace_inp_entry(inp, "pull-print-com2", nullptr);
1747 replace_inp_entry(inp, "gb-algorithm", nullptr);
1748 replace_inp_entry(inp, "nstgbradii", nullptr);
1749 replace_inp_entry(inp, "rgbradii", nullptr);
1750 replace_inp_entry(inp, "gb-epsilon-solvent", nullptr);
1751 replace_inp_entry(inp, "gb-saltconc", nullptr);
1752 replace_inp_entry(inp, "gb-obc-alpha", nullptr);
1753 replace_inp_entry(inp, "gb-obc-beta", nullptr);
1754 replace_inp_entry(inp, "gb-obc-gamma", nullptr);
1755 replace_inp_entry(inp, "gb-dielectric-offset", nullptr);
1756 replace_inp_entry(inp, "sa-algorithm", nullptr);
1757 replace_inp_entry(inp, "sa-surface-tension", nullptr);
1758 replace_inp_entry(inp, "ns-type", nullptr);
1760 /* replace the following commands with the clearer new versions*/
1761 replace_inp_entry(inp, "unconstrained-start", "continuation");
1762 replace_inp_entry(inp, "foreign-lambda", "fep-lambdas");
1763 replace_inp_entry(inp, "verlet-buffer-drift", "verlet-buffer-tolerance");
1764 replace_inp_entry(inp, "nstxtcout", "nstxout-compressed");
1765 replace_inp_entry(inp, "xtc-grps", "compressed-x-grps");
1766 replace_inp_entry(inp, "xtc-precision", "compressed-x-precision");
1767 replace_inp_entry(inp, "pull-print-com1", "pull-print-com");
1769 printStringNewline(&inp, "VARIOUS PREPROCESSING OPTIONS");
1770 printStringNoNewline(&inp, "Preprocessor information: use cpp syntax.");
1771 printStringNoNewline(&inp, "e.g.: -I/home/joe/doe -I/home/mary/roe");
1772 setStringEntry(&inp, "include", opts->include, nullptr);
1773 printStringNoNewline(&inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)");
1774 setStringEntry(&inp, "define", opts->define, nullptr);
1776 printStringNewline(&inp, "RUN CONTROL PARAMETERS");
1777 ir->eI = get_eeenum(&inp, "integrator", ei_names, wi);
1778 printStringNoNewline(&inp, "Start time and timestep in ps");
1779 ir->init_t = get_ereal(&inp, "tinit", 0.0, wi);
1780 ir->delta_t = get_ereal(&inp, "dt", 0.001, wi);
1781 ir->nsteps = get_eint64(&inp, "nsteps", 0, wi);
1782 printStringNoNewline(&inp, "For exact run continuation or redoing part of a run");
1783 ir->init_step = get_eint64(&inp, "init-step", 0, wi);
1784 printStringNoNewline(&inp, "Part index is updated automatically on checkpointing (keeps files separate)");
1785 ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
1786 printStringNoNewline(&inp, "mode for center of mass motion removal");
1787 ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi);
1788 printStringNoNewline(&inp, "number of steps for center of mass motion removal");
1789 ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi);
1790 printStringNoNewline(&inp, "group(s) for center of mass motion removal");
1791 setStringEntry(&inp, "comm-grps", is->vcm, nullptr);
1793 printStringNewline(&inp, "LANGEVIN DYNAMICS OPTIONS");
1794 printStringNoNewline(&inp, "Friction coefficient (amu/ps) and random seed");
1795 ir->bd_fric = get_ereal(&inp, "bd-fric", 0.0, wi);
1796 ir->ld_seed = get_eint64(&inp, "ld-seed", -1, wi);
1799 printStringNewline(&inp, "ENERGY MINIMIZATION OPTIONS");
1800 printStringNoNewline(&inp, "Force tolerance and initial step-size");
1801 ir->em_tol = get_ereal(&inp, "emtol", 10.0, wi);
1802 ir->em_stepsize = get_ereal(&inp, "emstep", 0.01, wi);
1803 printStringNoNewline(&inp, "Max number of iterations in relax-shells");
1804 ir->niter = get_eint(&inp, "niter", 20, wi);
1805 printStringNoNewline(&inp, "Step size (ps^2) for minimization of flexible constraints");
1806 ir->fc_stepsize = get_ereal(&inp, "fcstep", 0, wi);
1807 printStringNoNewline(&inp, "Frequency of steepest descents steps when doing CG");
1808 ir->nstcgsteep = get_eint(&inp, "nstcgsteep", 1000, wi);
1809 ir->nbfgscorr = get_eint(&inp, "nbfgscorr", 10, wi);
1811 printStringNewline(&inp, "TEST PARTICLE INSERTION OPTIONS");
1812 ir->rtpi = get_ereal(&inp, "rtpi", 0.05, wi);
1814 /* Output options */
1815 printStringNewline(&inp, "OUTPUT CONTROL OPTIONS");
1816 printStringNoNewline(&inp, "Output frequency for coords (x), velocities (v) and forces (f)");
1817 ir->nstxout = get_eint(&inp, "nstxout", 0, wi);
1818 ir->nstvout = get_eint(&inp, "nstvout", 0, wi);
1819 ir->nstfout = get_eint(&inp, "nstfout", 0, wi);
1820 printStringNoNewline(&inp, "Output frequency for energies to log file and energy file");
1821 ir->nstlog = get_eint(&inp, "nstlog", 1000, wi);
1822 ir->nstcalcenergy = get_eint(&inp, "nstcalcenergy", 100, wi);
1823 ir->nstenergy = get_eint(&inp, "nstenergy", 1000, wi);
1824 printStringNoNewline(&inp, "Output frequency and precision for .xtc file");
1825 ir->nstxout_compressed = get_eint(&inp, "nstxout-compressed", 0, wi);
1826 ir->x_compression_precision = get_ereal(&inp, "compressed-x-precision", 1000.0, wi);
1827 printStringNoNewline(&inp, "This selects the subset of atoms for the compressed");
1828 printStringNoNewline(&inp, "trajectory file. You can select multiple groups. By");
1829 printStringNoNewline(&inp, "default, all atoms will be written.");
1830 setStringEntry(&inp, "compressed-x-grps", is->x_compressed_groups, nullptr);
1831 printStringNoNewline(&inp, "Selection of energy groups");
1832 setStringEntry(&inp, "energygrps", is->energy, nullptr);
1834 /* Neighbor searching */
1835 printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
1836 printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)");
1837 ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi);
1838 printStringNoNewline(&inp, "nblist update frequency");
1839 ir->nstlist = get_eint(&inp, "nstlist", 10, wi);
1840 printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
1841 ir->ePBC = get_eeenum(&inp, "pbc", epbc_names, wi);
1842 ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0;
1843 printStringNoNewline(&inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
1844 printStringNoNewline(&inp, "a value of -1 means: use rlist");
1845 ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance", 0.005, wi);
1846 printStringNoNewline(&inp, "nblist cut-off");
1847 ir->rlist = get_ereal(&inp, "rlist", 1.0, wi);
1848 printStringNoNewline(&inp, "long-range cut-off for switched potentials");
1850 /* Electrostatics */
1851 printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
1852 printStringNoNewline(&inp, "Method for doing electrostatics");
1853 ir->coulombtype = get_eeenum(&inp, "coulombtype", eel_names, wi);
1854 ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi);
1855 printStringNoNewline(&inp, "cut-off lengths");
1856 ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi);
1857 ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi);
1858 printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
1859 ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi);
1860 ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
1861 printStringNoNewline(&inp, "Method for doing Van der Waals");
1862 ir->vdwtype = get_eeenum(&inp, "vdw-type", evdw_names, wi);
1863 ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi);
1864 printStringNoNewline(&inp, "cut-off lengths");
1865 ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi);
1866 ir->rvdw = get_ereal(&inp, "rvdw", 1.0, wi);
1867 printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
1868 ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi);
1869 printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
1870 ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
1871 printStringNoNewline(&inp, "Separate tables between energy group pairs");
1872 setStringEntry(&inp, "energygrp-table", is->egptable, nullptr);
1873 printStringNoNewline(&inp, "Spacing for the PME/PPPM FFT grid");
1874 ir->fourier_spacing = get_ereal(&inp, "fourierspacing", 0.12, wi);
1875 printStringNoNewline(&inp, "FFT grid size, when a value is 0 fourierspacing will be used");
1876 ir->nkx = get_eint(&inp, "fourier-nx", 0, wi);
1877 ir->nky = get_eint(&inp, "fourier-ny", 0, wi);
1878 ir->nkz = get_eint(&inp, "fourier-nz", 0, wi);
1879 printStringNoNewline(&inp, "EWALD/PME/PPPM parameters");
1880 ir->pme_order = get_eint(&inp, "pme-order", 4, wi);
1881 ir->ewald_rtol = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
1882 ir->ewald_rtol_lj = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
1883 ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
1884 ir->ewald_geometry = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
1885 ir->epsilon_surface = get_ereal(&inp, "epsilon-surface", 0.0, wi);
1887 /* Implicit solvation is no longer supported, but we need grompp
1888 to be able to refuse old .mdp files that would have built a tpr
1889 to run it. Thus, only "no" is accepted. */
1890 ir->implicit_solvent = (get_eeenum(&inp, "implicit-solvent", no_names, wi) != 0);
1892 /* Coupling stuff */
1893 printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
1894 printStringNoNewline(&inp, "Temperature coupling");
1895 ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
1896 ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi);
1897 ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
1898 ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
1899 printStringNoNewline(&inp, "Groups to couple separately");
1900 setStringEntry(&inp, "tc-grps", is->tcgrps, nullptr);
1901 printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
1902 setStringEntry(&inp, "tau-t", is->tau_t, nullptr);
1903 setStringEntry(&inp, "ref-t", is->ref_t, nullptr);
1904 printStringNoNewline(&inp, "pressure coupling");
1905 ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
1906 ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
1907 ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
1908 printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
1909 ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi);
1910 setStringEntry(&inp, "compressibility", dumstr[0], nullptr);
1911 setStringEntry(&inp, "ref-p", dumstr[1], nullptr);
1912 printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
1913 ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
1916 printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
1917 ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0);
1918 printStringNoNewline(&inp, "Groups treated Quantum Mechanically");
1919 setStringEntry(&inp, "QMMM-grps", is->QMMM, nullptr);
1920 printStringNoNewline(&inp, "QM method");
1921 setStringEntry(&inp, "QMmethod", is->QMmethod, nullptr);
1922 printStringNoNewline(&inp, "QMMM scheme");
1923 ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme", eQMMMscheme_names, wi);
1924 printStringNoNewline(&inp, "QM basisset");
1925 setStringEntry(&inp, "QMbasis", is->QMbasis, nullptr);
1926 printStringNoNewline(&inp, "QM charge");
1927 setStringEntry(&inp, "QMcharge", is->QMcharge, nullptr);
1928 printStringNoNewline(&inp, "QM multiplicity");
1929 setStringEntry(&inp, "QMmult", is->QMmult, nullptr);
1930 printStringNoNewline(&inp, "Surface Hopping");
1931 setStringEntry(&inp, "SH", is->bSH, nullptr);
1932 printStringNoNewline(&inp, "CAS space options");
1933 setStringEntry(&inp, "CASorbitals", is->CASorbitals, nullptr);
1934 setStringEntry(&inp, "CASelectrons", is->CASelectrons, nullptr);
1935 setStringEntry(&inp, "SAon", is->SAon, nullptr);
1936 setStringEntry(&inp, "SAoff", is->SAoff, nullptr);
1937 setStringEntry(&inp, "SAsteps", is->SAsteps, nullptr);
1938 printStringNoNewline(&inp, "Scale factor for MM charges");
1939 ir->scalefactor = get_ereal(&inp, "MMChargeScaleFactor", 1.0, wi);
1941 /* Simulated annealing */
1942 printStringNewline(&inp, "SIMULATED ANNEALING");
1943 printStringNoNewline(&inp, "Type of annealing for each temperature group (no/single/periodic)");
1944 setStringEntry(&inp, "annealing", is->anneal, nullptr);
1945 printStringNoNewline(&inp, "Number of time points to use for specifying annealing in each group");
1946 setStringEntry(&inp, "annealing-npoints", is->anneal_npoints, nullptr);
1947 printStringNoNewline(&inp, "List of times at the annealing points for each group");
1948 setStringEntry(&inp, "annealing-time", is->anneal_time, nullptr);
1949 printStringNoNewline(&inp, "Temp. at each annealing point, for each group.");
1950 setStringEntry(&inp, "annealing-temp", is->anneal_temp, nullptr);
1953 printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
1954 opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0);
1955 opts->tempi = get_ereal(&inp, "gen-temp", 300.0, wi);
1956 opts->seed = get_eint(&inp, "gen-seed", -1, wi);
1959 printStringNewline(&inp, "OPTIONS FOR BONDS");
1960 opts->nshake = get_eeenum(&inp, "constraints", constraints, wi);
1961 printStringNoNewline(&inp, "Type of constraint algorithm");
1962 ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
1963 printStringNoNewline(&inp, "Do not constrain the start configuration");
1964 ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0);
1965 printStringNoNewline(&inp, "Use successive overrelaxation to reduce the number of shake iterations");
1966 ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0);
1967 printStringNoNewline(&inp, "Relative tolerance of shake");
1968 ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
1969 printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
1970 ir->nProjOrder = get_eint(&inp, "lincs-order", 4, wi);
1971 printStringNoNewline(&inp, "Number of iterations in the final step of LINCS. 1 is fine for");
1972 printStringNoNewline(&inp, "normal simulations, but use 2 to conserve energy in NVE runs.");
1973 printStringNoNewline(&inp, "For energy minimization with constraints it should be 4 to 8.");
1974 ir->nLincsIter = get_eint(&inp, "lincs-iter", 1, wi);
1975 printStringNoNewline(&inp, "Lincs will write a warning to the stderr if in one step a bond");
1976 printStringNoNewline(&inp, "rotates over more degrees than");
1977 ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
1978 printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
1979 opts->bMorse = (get_eeenum(&inp, "morse", yesno_names, wi) != 0);
1981 /* Energy group exclusions */
1982 printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
1983 printStringNoNewline(&inp, "Pairs of energy groups for which all non-bonded interactions are excluded");
1984 setStringEntry(&inp, "energygrp-excl", is->egpexcl, nullptr);
1987 printStringNewline(&inp, "WALLS");
1988 printStringNoNewline(&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
1989 ir->nwall = get_eint(&inp, "nwall", 0, wi);
1990 ir->wall_type = get_eeenum(&inp, "wall-type", ewt_names, wi);
1991 ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
1992 setStringEntry(&inp, "wall-atomtype", is->wall_atomtype, nullptr);
1993 setStringEntry(&inp, "wall-density", is->wall_density, nullptr);
1994 ir->wall_ewald_zfac = get_ereal(&inp, "wall-ewald-zfac", 3, wi);
1997 printStringNewline(&inp, "COM PULLING");
1998 ir->bPull = (get_eeenum(&inp, "pull", yesno_names, wi) != 0);
2002 is->pull_grp = read_pullparams(&inp, ir->pull, wi);
2006 NOTE: needs COM pulling input */
2007 printStringNewline(&inp, "AWH biasing");
2008 ir->bDoAwh = (get_eeenum(&inp, "awh", yesno_names, wi) != 0);
2013 ir->awhParams = gmx::readAndCheckAwhParams(&inp, ir, wi);
2017 gmx_fatal(FARGS, "AWH biasing is only compatible with COM pulling turned on");
2021 /* Enforced rotation */
2022 printStringNewline(&inp, "ENFORCED ROTATION");
2023 printStringNoNewline(&inp, "Enforced rotation: No or Yes");
2024 ir->bRot = (get_eeenum(&inp, "rotation", yesno_names, wi) != 0);
2028 is->rot_grp = read_rotparams(&inp, ir->rot, wi);
2031 /* Interactive MD */
2033 printStringNewline(&inp, "Group to display and/or manipulate in interactive MD session");
2034 setStringEntry(&inp, "IMD-group", is->imd_grp, nullptr);
2035 if (is->imd_grp[0] != '\0')
2042 printStringNewline(&inp, "NMR refinement stuff");
2043 printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
2044 ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi);
2045 printStringNoNewline(&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
2046 ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
2047 printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
2048 ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0);
2049 ir->dr_fc = get_ereal(&inp, "disre-fc", 1000.0, wi);
2050 ir->dr_tau = get_ereal(&inp, "disre-tau", 0.0, wi);
2051 printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
2052 ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
2053 printStringNoNewline(&inp, "Orientation restraints: No or Yes");
2054 opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0);
2055 printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
2056 ir->orires_fc = get_ereal(&inp, "orire-fc", 0.0, wi);
2057 ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
2058 setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp, nullptr);
2059 printStringNoNewline(&inp, "Output frequency for trace(SD) and S to energy file");
2060 ir->nstorireout = get_eint(&inp, "nstorireout", 100, wi);
2062 /* free energy variables */
2063 printStringNewline(&inp, "Free energy variables");
2064 ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
2065 setStringEntry(&inp, "couple-moltype", is->couple_moltype, nullptr);
2066 opts->couple_lam0 = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
2067 opts->couple_lam1 = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
2068 opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0);
2070 fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
2072 it was not entered */
2073 fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
2074 fep->delta_lambda = get_ereal(&inp, "delta-lambda", 0.0, wi);
2075 fep->nstdhdl = get_eint(&inp, "nstdhdl", 50, wi);
2076 setStringEntry(&inp, "fep-lambdas", is->fep_lambda[efptFEP], nullptr);
2077 setStringEntry(&inp, "mass-lambdas", is->fep_lambda[efptMASS], nullptr);
2078 setStringEntry(&inp, "coul-lambdas", is->fep_lambda[efptCOUL], nullptr);
2079 setStringEntry(&inp, "vdw-lambdas", is->fep_lambda[efptVDW], nullptr);
2080 setStringEntry(&inp, "bonded-lambdas", is->fep_lambda[efptBONDED], nullptr);
2081 setStringEntry(&inp, "restraint-lambdas", is->fep_lambda[efptRESTRAINT], nullptr);
2082 setStringEntry(&inp, "temperature-lambdas", is->fep_lambda[efptTEMPERATURE], nullptr);
2083 fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
2084 setStringEntry(&inp, "init-lambda-weights", is->lambda_weights, nullptr);
2085 fep->edHdLPrintEnergy = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
2086 fep->sc_alpha = get_ereal(&inp, "sc-alpha", 0.0, wi);
2087 fep->sc_power = get_eint(&inp, "sc-power", 1, wi);
2088 fep->sc_r_power = get_ereal(&inp, "sc-r-power", 6.0, wi);
2089 fep->sc_sigma = get_ereal(&inp, "sc-sigma", 0.3, wi);
2090 fep->bScCoul = (get_eeenum(&inp, "sc-coul", yesno_names, wi) != 0);
2091 fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
2092 fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2093 fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
2094 fep->dhdl_derivatives = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
2095 fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
2096 fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2098 /* Non-equilibrium MD stuff */
2099 printStringNewline(&inp, "Non-equilibrium MD stuff");
2100 setStringEntry(&inp, "acc-grps", is->accgrps, nullptr);
2101 setStringEntry(&inp, "accelerate", is->acc, nullptr);
2102 setStringEntry(&inp, "freezegrps", is->freeze, nullptr);
2103 setStringEntry(&inp, "freezedim", is->frdim, nullptr);
2104 ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
2105 setStringEntry(&inp, "deform", is->deform, nullptr);
2107 /* simulated tempering variables */
2108 printStringNewline(&inp, "simulated tempering variables");
2109 ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0);
2110 ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
2111 ir->simtempvals->simtemp_low = get_ereal(&inp, "sim-temp-low", 300.0, wi);
2112 ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi);
2114 /* expanded ensemble variables */
2115 if (ir->efep == efepEXPANDED || ir->bSimTemp)
2117 read_expandedparams(&inp, expand, wi);
2120 /* Electric fields */
2122 gmx::KeyValueTreeObject convertedValues = flatKeyValueTreeFromInpFile(inp);
2123 gmx::KeyValueTreeTransformer transform;
2124 transform.rules()->addRule()
2125 .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
2126 mdModules->initMdpTransform(transform.rules());
2127 for (const auto &path : transform.mappedPaths())
2129 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
2130 mark_einp_set(inp, path[0].c_str());
2132 MdpErrorHandler errorHandler(wi);
2134 = transform.transform(convertedValues, &errorHandler);
2135 ir->params = new gmx::KeyValueTreeObject(result.object());
2136 mdModules->adjustInputrecBasedOnModules(ir);
2137 errorHandler.setBackMapping(result.backMapping());
2138 mdModules->assignOptionsToModules(*ir->params, &errorHandler);
2141 /* Ion/water position swapping ("computational electrophysiology") */
2142 printStringNewline(&inp, "Ion/water position swapping for computational electrophysiology setups");
2143 printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
2144 ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
2145 if (ir->eSwapCoords != eswapNO)
2152 printStringNoNewline(&inp, "Swap attempt frequency");
2153 ir->swap->nstswap = get_eint(&inp, "swap-frequency", 1, wi);
2154 printStringNoNewline(&inp, "Number of ion types to be controlled");
2155 nIonTypes = get_eint(&inp, "iontypes", 1, wi);
2158 warning_error(wi, "You need to provide at least one ion type for position exchanges.");
2160 ir->swap->ngrp = nIonTypes + eSwapFixedGrpNR;
2161 snew(ir->swap->grp, ir->swap->ngrp);
2162 for (i = 0; i < ir->swap->ngrp; i++)
2164 snew(ir->swap->grp[i].molname, STRLEN);
2166 printStringNoNewline(&inp, "Two index groups that contain the compartment-partitioning atoms");
2167 setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
2168 setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
2169 printStringNoNewline(&inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used");
2170 ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0);
2171 ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0);
2173 printStringNoNewline(&inp, "Name of solvent molecules");
2174 setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
2176 printStringNoNewline(&inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)");
2177 printStringNoNewline(&inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,");
2178 printStringNoNewline(&inp, "however, if correctly defined, the permeation events are recorded per channel");
2179 ir->swap->cyl0r = get_ereal(&inp, "cyl0-r", 2.0, wi);
2180 ir->swap->cyl0u = get_ereal(&inp, "cyl0-up", 1.0, wi);
2181 ir->swap->cyl0l = get_ereal(&inp, "cyl0-down", 1.0, wi);
2182 ir->swap->cyl1r = get_ereal(&inp, "cyl1-r", 2.0, wi);
2183 ir->swap->cyl1u = get_ereal(&inp, "cyl1-up", 1.0, wi);
2184 ir->swap->cyl1l = get_ereal(&inp, "cyl1-down", 1.0, wi);
2186 printStringNoNewline(&inp, "Average the number of ions per compartment over these many swap attempt steps");
2187 ir->swap->nAverage = get_eint(&inp, "coupl-steps", 10, wi);
2189 printStringNoNewline(&inp, "Names of the ion types that can be exchanged with solvent molecules,");
2190 printStringNoNewline(&inp, "and the requested number of ions of this type in compartments A and B");
2191 printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
2192 for (i = 0; i < nIonTypes; i++)
2194 int ig = eSwapFixedGrpNR + i;
2196 sprintf(buf, "iontype%d-name", i);
2197 setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
2198 sprintf(buf, "iontype%d-in-A", i);
2199 ir->swap->grp[ig].nmolReq[0] = get_eint(&inp, buf, -1, wi);
2200 sprintf(buf, "iontype%d-in-B", i);
2201 ir->swap->grp[ig].nmolReq[1] = get_eint(&inp, buf, -1, wi);
2204 printStringNoNewline(&inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
2205 printStringNoNewline(&inp, "at maximum distance (= bulk concentration) to the split group layers. However,");
2206 printStringNoNewline(&inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
2207 printStringNoNewline(&inp, "towards one of the compartment-partitioning layers (at +/- 1.0).");
2208 ir->swap->bulkOffset[0] = get_ereal(&inp, "bulk-offsetA", 0.0, wi);
2209 ir->swap->bulkOffset[1] = get_ereal(&inp, "bulk-offsetB", 0.0, wi);
2210 if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0)
2211 || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) )
2213 warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !");
2216 printStringNoNewline(&inp, "Start to swap ions if threshold difference to requested count is reached");
2217 ir->swap->threshold = get_ereal(&inp, "threshold", 1.0, wi);
2220 /* AdResS is no longer supported, but we need grompp to be able to
2221 refuse to process old .mdp files that used it. */
2222 ir->bAdress = (get_eeenum(&inp, "adress", no_names, wi) != 0);
2224 /* User defined thingies */
2225 printStringNewline(&inp, "User defined thingies");
2226 setStringEntry(&inp, "user1-grps", is->user1, nullptr);
2227 setStringEntry(&inp, "user2-grps", is->user2, nullptr);
2228 ir->userint1 = get_eint(&inp, "userint1", 0, wi);
2229 ir->userint2 = get_eint(&inp, "userint2", 0, wi);
2230 ir->userint3 = get_eint(&inp, "userint3", 0, wi);
2231 ir->userint4 = get_eint(&inp, "userint4", 0, wi);
2232 ir->userreal1 = get_ereal(&inp, "userreal1", 0, wi);
2233 ir->userreal2 = get_ereal(&inp, "userreal2", 0, wi);
2234 ir->userreal3 = get_ereal(&inp, "userreal3", 0, wi);
2235 ir->userreal4 = get_ereal(&inp, "userreal4", 0, wi);
2239 gmx::TextOutputFile stream(mdparout);
2240 write_inpfile(&stream, mdparout, &inp, FALSE, writeMdpHeader, wi);
2242 // Transform module data into a flat key-value tree for output.
2243 gmx::KeyValueTreeBuilder builder;
2244 gmx::KeyValueTreeObjectBuilder builderObject = builder.rootObject();
2245 mdModules->buildMdpOutput(&builderObject);
2247 gmx::TextWriter writer(&stream);
2248 writeKeyValueTreeAsMdp(&writer, builder.build());
2253 /* Process options if necessary */
2254 for (m = 0; m < 2; m++)
2256 for (i = 0; i < 2*DIM; i++)
2265 if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1)
2267 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 1)");
2269 dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX];
2271 case epctSEMIISOTROPIC:
2272 case epctSURFACETENSION:
2273 if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2)
2275 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 2)");
2277 dumdub[m][YY] = dumdub[m][XX];
2279 case epctANISOTROPIC:
2280 if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf",
2281 &(dumdub[m][XX]), &(dumdub[m][YY]), &(dumdub[m][ZZ]),
2282 &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5])) != 6)
2284 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 6)");
2288 gmx_fatal(FARGS, "Pressure coupling type %s not implemented yet",
2289 epcoupltype_names[ir->epct]);
2293 clear_mat(ir->ref_p);
2294 clear_mat(ir->compress);
2295 for (i = 0; i < DIM; i++)
2297 ir->ref_p[i][i] = dumdub[1][i];
2298 ir->compress[i][i] = dumdub[0][i];
2300 if (ir->epct == epctANISOTROPIC)
2302 ir->ref_p[XX][YY] = dumdub[1][3];
2303 ir->ref_p[XX][ZZ] = dumdub[1][4];
2304 ir->ref_p[YY][ZZ] = dumdub[1][5];
2305 if (ir->ref_p[XX][YY] != 0 && ir->ref_p[XX][ZZ] != 0 && ir->ref_p[YY][ZZ] != 0)
2307 warning(wi, "All off-diagonal reference pressures are non-zero. Are you sure you want to apply a threefold shear stress?\n");
2309 ir->compress[XX][YY] = dumdub[0][3];
2310 ir->compress[XX][ZZ] = dumdub[0][4];
2311 ir->compress[YY][ZZ] = dumdub[0][5];
2312 for (i = 0; i < DIM; i++)
2314 for (m = 0; m < i; m++)
2316 ir->ref_p[i][m] = ir->ref_p[m][i];
2317 ir->compress[i][m] = ir->compress[m][i];
2322 if (ir->comm_mode == ecmNO)
2327 opts->couple_moltype = nullptr;
2328 if (strlen(is->couple_moltype) > 0)
2330 if (ir->efep != efepNO)
2332 opts->couple_moltype = gmx_strdup(is->couple_moltype);
2333 if (opts->couple_lam0 == opts->couple_lam1)
2335 warning(wi, "The lambda=0 and lambda=1 states for coupling are identical");
2337 if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE ||
2338 opts->couple_lam1 == ecouplamNONE))
2340 warning(wi, "For proper sampling of the (nearly) decoupled state, stochastic dynamics should be used");
2345 warning_note(wi, "Free energy is turned off, so we will not decouple the molecule listed in your input.");
2348 /* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */
2349 if (ir->efep != efepNO)
2351 if (fep->delta_lambda > 0)
2353 ir->efep = efepSLOWGROWTH;
2357 if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES)
2359 fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2360 warning_note(wi, "Old option for dhdl-print-energy given: "
2361 "changing \"yes\" to \"total\"\n");
2364 if (ir->bSimTemp && (fep->edHdLPrintEnergy == edHdLPrintEnergyNO))
2366 /* always print out the energy to dhdl if we are doing
2367 expanded ensemble, since we need the total energy for
2368 analysis if the temperature is changing. In some
2369 conditions one may only want the potential energy, so
2370 we will allow that if the appropriate mdp setting has
2371 been enabled. Otherwise, total it is:
2373 fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2376 if ((ir->efep != efepNO) || ir->bSimTemp)
2378 ir->bExpanded = FALSE;
2379 if ((ir->efep == efepEXPANDED) || ir->bSimTemp)
2381 ir->bExpanded = TRUE;
2383 do_fep_params(ir, is->fep_lambda, is->lambda_weights, wi);
2384 if (ir->bSimTemp) /* done after fep params */
2386 do_simtemp_params(ir);
2389 /* Because sc-coul (=FALSE by default) only acts on the lambda state
2390 * setup and not on the old way of specifying the free-energy setup,
2391 * we should check for using soft-core when not needed, since that
2392 * can complicate the sampling significantly.
2393 * Note that we only check for the automated coupling setup.
2394 * If the (advanced) user does FEP through manual topology changes,
2395 * this check will not be triggered.
2397 if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 &&
2398 ir->fepvals->sc_alpha != 0 &&
2399 (couple_lambda_has_vdw_on(opts->couple_lam0) &&
2400 couple_lambda_has_vdw_on(opts->couple_lam1)))
2402 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.");
2407 ir->fepvals->n_lambda = 0;
2410 /* WALL PARAMETERS */
2412 do_wall_params(ir, is->wall_atomtype, is->wall_density, opts, wi);
2414 /* ORIENTATION RESTRAINT PARAMETERS */
2416 if (opts->bOrire && gmx::splitString(is->orirefitgrp).size() != 1)
2418 warning_error(wi, "ERROR: Need one orientation restraint fit group\n");
2421 /* DEFORMATION PARAMETERS */
2423 clear_mat(ir->deform);
2424 for (i = 0; i < 6; i++)
2429 double gmx_unused canary;
2430 int ndeform = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf %lf",
2431 &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]),
2432 &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]), &canary);
2434 if (strlen(is->deform) > 0 && ndeform != 6)
2436 warning_error(wi, gmx::formatString("Cannot parse exactly 6 box deformation velocities from string '%s'", is->deform).c_str());
2438 for (i = 0; i < 3; i++)
2440 ir->deform[i][i] = dumdub[0][i];
2442 ir->deform[YY][XX] = dumdub[0][3];
2443 ir->deform[ZZ][XX] = dumdub[0][4];
2444 ir->deform[ZZ][YY] = dumdub[0][5];
2445 if (ir->epc != epcNO)
2447 for (i = 0; i < 3; i++)
2449 for (j = 0; j <= i; j++)
2451 if (ir->deform[i][j] != 0 && ir->compress[i][j] != 0)
2453 warning_error(wi, "A box element has deform set and compressibility > 0");
2457 for (i = 0; i < 3; i++)
2459 for (j = 0; j < i; j++)
2461 if (ir->deform[i][j] != 0)
2463 for (m = j; m < DIM; m++)
2465 if (ir->compress[m][j] != 0)
2467 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.");
2468 warning(wi, warn_buf);
2476 /* Ion/water position swapping checks */
2477 if (ir->eSwapCoords != eswapNO)
2479 if (ir->swap->nstswap < 1)
2481 warning_error(wi, "swap_frequency must be 1 or larger when ion swapping is requested");
2483 if (ir->swap->nAverage < 1)
2485 warning_error(wi, "coupl_steps must be 1 or larger.\n");
2487 if (ir->swap->threshold < 1.0)
2489 warning_error(wi, "Ion count threshold must be at least 1.\n");
2497 static int search_QMstring(const char *s, int ng, const char *gn[])
2499 /* same as normal search_string, but this one searches QM strings */
2502 for (i = 0; (i < ng); i++)
2504 if (gmx_strcasecmp(s, gn[i]) == 0)
2510 gmx_fatal(FARGS, "this QM method or basisset (%s) is not implemented\n!", s);
2511 } /* search_QMstring */
2513 /* We would like gn to be const as well, but C doesn't allow this */
2514 /* TODO this is utility functionality (search for the index of a
2515 string in a collection), so should be refactored and located more
2517 int search_string(const char *s, int ng, char *gn[])
2521 for (i = 0; (i < ng); i++)
2523 if (gmx_strcasecmp(s, gn[i]) == 0)
2530 "Group %s referenced in the .mdp file was not found in the index file.\n"
2531 "Group names must match either [moleculetype] names or custom index group\n"
2532 "names, in which case you must supply an index file to the '-n' option\n"
2537 static bool do_numbering(int natoms, SimulationGroups *groups,
2538 gmx::ArrayRef<std::string> groupsFromMdpFile,
2539 t_blocka *block, char *gnames[],
2540 SimulationAtomGroupType gtype, int restnm,
2541 int grptp, bool bVerbose,
2544 unsigned short *cbuf;
2545 AtomGroupIndices *grps = &(groups->groups[gtype]);
2546 int j, gid, aj, ognr, ntot = 0;
2549 char warn_buf[STRLEN];
2551 title = shortName(gtype);
2554 /* Mark all id's as not set */
2555 for (int i = 0; (i < natoms); i++)
2560 for (int i = 0; i != groupsFromMdpFile.ssize(); ++i)
2562 /* Lookup the group name in the block structure */
2563 gid = search_string(groupsFromMdpFile[i].c_str(), block->nr, gnames);
2564 if ((grptp != egrptpONE) || (i == 0))
2566 grps->emplace_back(gid);
2569 /* Now go over the atoms in the group */
2570 for (j = block->index[gid]; (j < block->index[gid+1]); j++)
2575 /* Range checking */
2576 if ((aj < 0) || (aj >= natoms))
2578 gmx_fatal(FARGS, "Invalid atom number %d in indexfile", aj + 1);
2580 /* Lookup up the old group number */
2584 gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)",
2585 aj+1, title, ognr+1, i+1);
2589 /* Store the group number in buffer */
2590 if (grptp == egrptpONE)
2603 /* Now check whether we have done all atoms */
2607 if (grptp == egrptpALL)
2609 gmx_fatal(FARGS, "%d atoms are not part of any of the %s groups",
2610 natoms-ntot, title);
2612 else if (grptp == egrptpPART)
2614 sprintf(warn_buf, "%d atoms are not part of any of the %s groups",
2615 natoms-ntot, title);
2616 warning_note(wi, warn_buf);
2618 /* Assign all atoms currently unassigned to a rest group */
2619 for (j = 0; (j < natoms); j++)
2621 if (cbuf[j] == NOGID)
2623 cbuf[j] = grps->size();
2627 if (grptp != egrptpPART)
2632 "Making dummy/rest group for %s containing %d elements\n",
2633 title, natoms-ntot);
2635 /* Add group name "rest" */
2636 grps->emplace_back(restnm);
2638 /* Assign the rest name to all atoms not currently assigned to a group */
2639 for (j = 0; (j < natoms); j++)
2641 if (cbuf[j] == NOGID)
2643 // group size was not updated before this here, so need to use -1.
2644 cbuf[j] = grps->size() - 1;
2650 if (grps->size() == 1 && (ntot == 0 || ntot == natoms))
2652 /* All atoms are part of one (or no) group, no index required */
2653 groups->groupNumbers[gtype].clear();
2657 for (int j = 0; (j < natoms); j++)
2659 groups->groupNumbers[gtype].emplace_back(cbuf[j]);
2665 return (bRest && grptp == egrptpPART);
2668 static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
2671 pull_params_t *pull;
2672 int natoms, imin, jmin;
2673 int *nrdf2, *na_vcm, na_tot;
2674 double *nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub;
2679 * First calc 3xnr-atoms for each group
2680 * then subtract half a degree of freedom for each constraint
2682 * Only atoms and nuclei contribute to the degrees of freedom...
2687 const SimulationGroups &groups = mtop->groups;
2688 natoms = mtop->natoms;
2690 /* Allocate one more for a possible rest group */
2691 /* We need to sum degrees of freedom into doubles,
2692 * since floats give too low nrdf's above 3 million atoms.
2694 snew(nrdf_tc, groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()+1);
2695 snew(nrdf_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2696 snew(dof_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2697 snew(na_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2698 snew(nrdf_vcm_sub, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2700 for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++)
2704 for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; i++)
2707 clear_ivec(dof_vcm[i]);
2709 nrdf_vcm_sub[i] = 0;
2711 snew(nrdf2, natoms);
2712 for (const AtomProxy atomP : AtomRange(*mtop))
2714 const t_atom &local = atomP.atom();
2715 int i = atomP.globalAtomNumber();
2717 if (local.ptype == eptAtom || local.ptype == eptNucleus)
2719 int g = getGroupType(groups, SimulationAtomGroupType::Freeze, i);
2720 for (int d = 0; d < DIM; d++)
2722 if (opts->nFreeze[g][d] == 0)
2724 /* Add one DOF for particle i (counted as 2*1) */
2726 /* VCM group i has dim d as a DOF */
2727 dof_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)][d] = 1;
2730 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, i)] += 0.5*nrdf2[i];
2731 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)] += 0.5*nrdf2[i];
2736 for (const gmx_molblock_t &molb : mtop->molblock)
2738 const gmx_moltype_t &molt = mtop->moltype[molb.type];
2739 const t_atom *atom = molt.atoms.atom;
2740 for (int mol = 0; mol < molb.nmol; mol++)
2742 for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
2744 gmx::ArrayRef<const int> ia = molt.ilist[ftype].iatoms;
2745 for (int i = 0; i < molt.ilist[ftype].size(); )
2747 /* Subtract degrees of freedom for the constraints,
2748 * if the particles still have degrees of freedom left.
2749 * If one of the particles is a vsite or a shell, then all
2750 * constraint motion will go there, but since they do not
2751 * contribute to the constraints the degrees of freedom do not
2754 int ai = as + ia[i + 1];
2755 int aj = as + ia[i + 2];
2756 if (((atom[ia[i + 1]].ptype == eptNucleus) ||
2757 (atom[ia[i + 1]].ptype == eptAtom)) &&
2758 ((atom[ia[i + 2]].ptype == eptNucleus) ||
2759 (atom[ia[i + 2]].ptype == eptAtom)))
2777 imin = std::min(imin, nrdf2[ai]);
2778 jmin = std::min(jmin, nrdf2[aj]);
2781 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin;
2782 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, aj)] -= 0.5*jmin;
2783 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
2784 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, aj)] -= 0.5*jmin;
2786 i += interaction_function[ftype].nratoms+1;
2789 gmx::ArrayRef<const int> ia = molt.ilist[F_SETTLE].iatoms;
2790 for (int i = 0; i < molt.ilist[F_SETTLE].size(); )
2792 /* Subtract 1 dof from every atom in the SETTLE */
2793 for (int j = 0; j < 3; j++)
2795 int ai = as + ia[i + 1 + j];
2796 imin = std::min(2, nrdf2[ai]);
2798 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin;
2799 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
2803 as += molt.atoms.nr;
2809 /* Correct nrdf for the COM constraints.
2810 * We correct using the TC and VCM group of the first atom
2811 * in the reference and pull group. If atoms in one pull group
2812 * belong to different TC or VCM groups it is anyhow difficult
2813 * to determine the optimal nrdf assignment.
2817 for (int i = 0; i < pull->ncoord; i++)
2819 if (pull->coord[i].eType != epullCONSTRAINT)
2826 for (int j = 0; j < 2; j++)
2828 const t_pull_group *pgrp;
2830 pgrp = &pull->group[pull->coord[i].group[j]];
2834 /* Subtract 1/2 dof from each group */
2835 int ai = pgrp->ind[0];
2836 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin;
2837 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
2838 if (nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] < 0)
2840 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.groups[SimulationAtomGroupType::TemperatureCoupling][getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)]]);
2845 /* We need to subtract the whole DOF from group j=1 */
2852 if (ir->nstcomm != 0)
2856 /* We remove COM motion up to dim ndof_com() */
2857 ndim_rm_vcm = ndof_com(ir);
2859 /* Subtract ndim_rm_vcm (or less with frozen dimensions) from
2860 * the number of degrees of freedom in each vcm group when COM
2861 * translation is removed and 6 when rotation is removed as well.
2863 for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++)
2865 switch (ir->comm_mode)
2868 case ecmLINEAR_ACCELERATION_CORRECTION:
2869 nrdf_vcm_sub[j] = 0;
2870 for (int d = 0; d < ndim_rm_vcm; d++)
2879 nrdf_vcm_sub[j] = 6;
2882 gmx_incons("Checking comm_mode");
2886 for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++)
2888 /* Count the number of atoms of TC group i for every VCM group */
2889 for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++)
2894 for (int ai = 0; ai < natoms; ai++)
2896 if (getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai) == i)
2898 na_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)]++;
2902 /* Correct for VCM removal according to the fraction of each VCM
2903 * group present in this TC group.
2905 nrdf_uc = nrdf_tc[i];
2907 for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++)
2909 if (nrdf_vcm[j] > nrdf_vcm_sub[j])
2911 nrdf_tc[i] += nrdf_uc*(static_cast<double>(na_vcm[j])/static_cast<double>(na_tot))*
2912 (nrdf_vcm[j] - nrdf_vcm_sub[j])/nrdf_vcm[j];
2917 for (int i = 0; (i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling])); i++)
2919 opts->nrdf[i] = nrdf_tc[i];
2920 if (opts->nrdf[i] < 0)
2925 "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
2926 gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]], opts->nrdf[i]);
2934 sfree(nrdf_vcm_sub);
2937 static bool do_egp_flag(t_inputrec *ir, SimulationGroups *groups,
2938 const char *option, const char *val, int flag)
2940 /* The maximum number of energy group pairs would be MAXPTR*(MAXPTR+1)/2.
2941 * But since this is much larger than STRLEN, such a line can not be parsed.
2942 * The real maximum is the number of names that fit in a string: STRLEN/2.
2944 #define EGP_MAX (STRLEN/2)
2948 auto names = gmx::splitString(val);
2949 if (names.size() % 2 != 0)
2951 gmx_fatal(FARGS, "The number of groups for %s is odd", option);
2953 nr = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
2955 for (size_t i = 0; i < names.size() / 2; i++)
2957 // TODO this needs to be replaced by a solution using std::find_if
2960 gmx_strcasecmp(names[2*i].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]])))
2966 gmx_fatal(FARGS, "%s in %s is not an energy group\n",
2967 names[2*i].c_str(), option);
2971 gmx_strcasecmp(names[2*i+1].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]])))
2977 gmx_fatal(FARGS, "%s in %s is not an energy group\n",
2978 names[2*i+1].c_str(), option);
2980 if ((j < nr) && (k < nr))
2982 ir->opts.egp_flags[nr*j+k] |= flag;
2983 ir->opts.egp_flags[nr*k+j] |= flag;
2992 static void make_swap_groups(
2997 int ig = -1, i = 0, gind;
3001 /* Just a quick check here, more thorough checks are in mdrun */
3002 if (strcmp(swap->grp[eGrpSplit0].molname, swap->grp[eGrpSplit1].molname) == 0)
3004 gmx_fatal(FARGS, "The split groups can not both be '%s'.", swap->grp[eGrpSplit0].molname);
3007 /* Get the index atoms of the split0, split1, solvent, and swap groups */
3008 for (ig = 0; ig < swap->ngrp; ig++)
3010 swapg = &swap->grp[ig];
3011 gind = search_string(swap->grp[ig].molname, grps->nr, gnames);
3012 swapg->nat = grps->index[gind+1] - grps->index[gind];
3016 fprintf(stderr, "%s group '%s' contains %d atoms.\n",
3017 ig < 3 ? eSwapFixedGrp_names[ig] : "Swap",
3018 swap->grp[ig].molname, swapg->nat);
3019 snew(swapg->ind, swapg->nat);
3020 for (i = 0; i < swapg->nat; i++)
3022 swapg->ind[i] = grps->a[grps->index[gind]+i];
3027 gmx_fatal(FARGS, "Swap group %s does not contain any atoms.", swap->grp[ig].molname);
3033 static void make_IMD_group(t_IMD *IMDgroup, char *IMDgname, t_blocka *grps, char **gnames)
3038 ig = search_string(IMDgname, grps->nr, gnames);
3039 IMDgroup->nat = grps->index[ig+1] - grps->index[ig];
3041 if (IMDgroup->nat > 0)
3043 fprintf(stderr, "Group '%s' with %d atoms can be activated for interactive molecular dynamics (IMD).\n",
3044 IMDgname, IMDgroup->nat);
3045 snew(IMDgroup->ind, IMDgroup->nat);
3046 for (i = 0; i < IMDgroup->nat; i++)
3048 IMDgroup->ind[i] = grps->a[grps->index[ig]+i];
3053 void do_index(const char* mdparin, const char *ndx,
3056 const gmx::MdModulesNotifier ¬ifier,
3060 t_blocka *defaultIndexGroups;
3064 char warnbuf[STRLEN], **gnames;
3068 int i, j, k, restnm;
3069 bool bExcl, bTable, bAnneal, bRest;
3070 char warn_buf[STRLEN];
3074 fprintf(stderr, "processing index file...\n");
3078 snew(defaultIndexGroups, 1);
3079 snew(defaultIndexGroups->index, 1);
3081 atoms_all = gmx_mtop_global_atoms(mtop);
3082 analyse(&atoms_all, defaultIndexGroups, &gnames, FALSE, TRUE);
3083 done_atom(&atoms_all);
3087 defaultIndexGroups = init_index(ndx, &gnames);
3090 SimulationGroups *groups = &mtop->groups;
3091 natoms = mtop->natoms;
3092 symtab = &mtop->symtab;
3094 for (int i = 0; (i < defaultIndexGroups->nr); i++)
3096 groups->groupNames.emplace_back(put_symtab(symtab, gnames[i]));
3098 groups->groupNames.emplace_back(put_symtab(symtab, "rest"));
3099 restnm = groups->groupNames.size() - 1;
3100 GMX_RELEASE_ASSERT(restnm == defaultIndexGroups->nr, "Size of allocations must match");
3101 srenew(gnames, defaultIndexGroups->nr+1);
3102 gnames[restnm] = *(groups->groupNames.back());
3104 set_warning_line(wi, mdparin, -1);
3106 auto temperatureCouplingTauValues = gmx::splitString(is->tau_t);
3107 auto temperatureCouplingReferenceValues = gmx::splitString(is->ref_t);
3108 auto temperatureCouplingGroupNames = gmx::splitString(is->tcgrps);
3109 if (temperatureCouplingTauValues.size() != temperatureCouplingGroupNames.size() ||
3110 temperatureCouplingReferenceValues.size() != temperatureCouplingGroupNames.size())
3112 gmx_fatal(FARGS, "Invalid T coupling input: %zu groups, %zu ref-t values and "
3114 temperatureCouplingGroupNames.size(),
3115 temperatureCouplingReferenceValues.size(),
3116 temperatureCouplingTauValues.size());
3119 const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
3120 do_numbering(natoms, groups, temperatureCouplingGroupNames, defaultIndexGroups, gnames,
3121 SimulationAtomGroupType::TemperatureCoupling,
3122 restnm, useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
3123 nr = groups->groups[SimulationAtomGroupType::TemperatureCoupling].size();
3125 snew(ir->opts.nrdf, nr);
3126 snew(ir->opts.tau_t, nr);
3127 snew(ir->opts.ref_t, nr);
3128 if (ir->eI == eiBD && ir->bd_fric == 0)
3130 fprintf(stderr, "bd-fric=0, so tau-t will be used as the inverse friction constant(s)\n");
3133 if (useReferenceTemperature)
3135 if (size_t(nr) != temperatureCouplingReferenceValues.size())
3137 gmx_fatal(FARGS, "Not enough ref-t and tau-t values!");
3141 convertReals(wi, temperatureCouplingTauValues, "tau-t", ir->opts.tau_t);
3142 for (i = 0; (i < nr); i++)
3144 if ((ir->eI == eiBD) && ir->opts.tau_t[i] <= 0)
3146 sprintf(warn_buf, "With integrator %s tau-t should be larger than 0", ei_names[ir->eI]);
3147 warning_error(wi, warn_buf);
3150 if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
3152 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.");
3155 if (ir->opts.tau_t[i] >= 0)
3157 tau_min = std::min(tau_min, ir->opts.tau_t[i]);
3160 if (ir->etc != etcNO && ir->nsttcouple == -1)
3162 ir->nsttcouple = ir_optimal_nsttcouple(ir);
3167 if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
3169 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");
3171 if (ir->epc == epcMTTK)
3173 if (ir->etc != etcNOSEHOOVER)
3175 gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
3179 if (ir->nstpcouple != ir->nsttcouple)
3181 int mincouple = std::min(ir->nstpcouple, ir->nsttcouple);
3182 ir->nstpcouple = ir->nsttcouple = mincouple;
3183 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);
3184 warning_note(wi, warn_buf);
3189 /* velocity verlet with averaged kinetic energy KE = 0.5*(v(t+1/2) - v(t-1/2)) is implemented
3190 primarily for testing purposes, and does not work with temperature coupling other than 1 */
3192 if (ETC_ANDERSEN(ir->etc))
3194 if (ir->nsttcouple != 1)
3197 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");
3198 warning_note(wi, warn_buf);
3201 nstcmin = tcouple_min_integration_steps(ir->etc);
3204 if (tau_min/(ir->delta_t*ir->nsttcouple) < nstcmin - 10*GMX_REAL_EPS)
3206 sprintf(warn_buf, "For proper integration of the %s thermostat, tau-t (%g) should be at least %d times larger than nsttcouple*dt (%g)",
3207 ETCOUPLTYPE(ir->etc),
3209 ir->nsttcouple*ir->delta_t);
3210 warning(wi, warn_buf);
3213 convertReals(wi, temperatureCouplingReferenceValues, "ref-t", ir->opts.ref_t);
3214 for (i = 0; (i < nr); i++)
3216 if (ir->opts.ref_t[i] < 0)
3218 gmx_fatal(FARGS, "ref-t for group %d negative", i);
3221 /* set the lambda mc temperature to the md integrator temperature (which should be defined
3222 if we are in this conditional) if mc_temp is negative */
3223 if (ir->expandedvals->mc_temp < 0)
3225 ir->expandedvals->mc_temp = ir->opts.ref_t[0]; /*for now, set to the first reft */
3229 /* Simulated annealing for each group. There are nr groups */
3230 auto simulatedAnnealingGroupNames = gmx::splitString(is->anneal);
3231 if (simulatedAnnealingGroupNames.size() == 1 &&
3232 gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[0], "N", 1))
3234 simulatedAnnealingGroupNames.resize(0);
3236 if (!simulatedAnnealingGroupNames.empty() &&
3237 gmx::ssize(simulatedAnnealingGroupNames) != nr)
3239 gmx_fatal(FARGS, "Wrong number of annealing values: %zu (for %d groups)\n",
3240 simulatedAnnealingGroupNames.size(), nr);
3244 snew(ir->opts.annealing, nr);
3245 snew(ir->opts.anneal_npoints, nr);
3246 snew(ir->opts.anneal_time, nr);
3247 snew(ir->opts.anneal_temp, nr);
3248 for (i = 0; i < nr; i++)
3250 ir->opts.annealing[i] = eannNO;
3251 ir->opts.anneal_npoints[i] = 0;
3252 ir->opts.anneal_time[i] = nullptr;
3253 ir->opts.anneal_temp[i] = nullptr;
3255 if (!simulatedAnnealingGroupNames.empty())
3258 for (i = 0; i < nr; i++)
3260 if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "N", 1))
3262 ir->opts.annealing[i] = eannNO;
3264 else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "S", 1))
3266 ir->opts.annealing[i] = eannSINGLE;
3269 else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "P", 1))
3271 ir->opts.annealing[i] = eannPERIODIC;
3277 /* Read the other fields too */
3278 auto simulatedAnnealingPoints = gmx::splitString(is->anneal_npoints);
3279 if (simulatedAnnealingPoints.size() != simulatedAnnealingGroupNames.size())
3281 gmx_fatal(FARGS, "Found %zu annealing-npoints values for %zu groups\n",
3282 simulatedAnnealingPoints.size(), simulatedAnnealingGroupNames.size());
3284 convertInts(wi, simulatedAnnealingPoints, "annealing points", ir->opts.anneal_npoints);
3285 size_t numSimulatedAnnealingFields = 0;
3286 for (i = 0; i < nr; i++)
3288 if (ir->opts.anneal_npoints[i] == 1)
3290 gmx_fatal(FARGS, "Please specify at least a start and an end point for annealing\n");
3292 snew(ir->opts.anneal_time[i], ir->opts.anneal_npoints[i]);
3293 snew(ir->opts.anneal_temp[i], ir->opts.anneal_npoints[i]);
3294 numSimulatedAnnealingFields += ir->opts.anneal_npoints[i];
3297 auto simulatedAnnealingTimes = gmx::splitString(is->anneal_time);
3299 if (simulatedAnnealingTimes.size() != numSimulatedAnnealingFields)
3301 gmx_fatal(FARGS, "Found %zu annealing-time values, wanted %zu\n",
3302 simulatedAnnealingTimes.size(), numSimulatedAnnealingFields);
3304 auto simulatedAnnealingTemperatures = gmx::splitString(is->anneal_temp);
3305 if (simulatedAnnealingTemperatures.size() != numSimulatedAnnealingFields)
3307 gmx_fatal(FARGS, "Found %zu annealing-temp values, wanted %zu\n",
3308 simulatedAnnealingTemperatures.size(), numSimulatedAnnealingFields);
3311 std::vector<real> allSimulatedAnnealingTimes(numSimulatedAnnealingFields);
3312 std::vector<real> allSimulatedAnnealingTemperatures(numSimulatedAnnealingFields);
3313 convertReals(wi, simulatedAnnealingTimes, "anneal-time", allSimulatedAnnealingTimes.data());
3314 convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp", allSimulatedAnnealingTemperatures.data());
3315 for (i = 0, k = 0; i < nr; i++)
3317 for (j = 0; j < ir->opts.anneal_npoints[i]; j++)
3319 ir->opts.anneal_time[i][j] = allSimulatedAnnealingTimes[k];
3320 ir->opts.anneal_temp[i][j] = allSimulatedAnnealingTemperatures[k];
3323 if (ir->opts.anneal_time[i][0] > (ir->init_t+GMX_REAL_EPS))
3325 gmx_fatal(FARGS, "First time point for annealing > init_t.\n");
3331 if (ir->opts.anneal_time[i][j] < ir->opts.anneal_time[i][j-1])
3333 gmx_fatal(FARGS, "Annealing timepoints out of order: t=%f comes after t=%f\n",
3334 ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j-1]);
3337 if (ir->opts.anneal_temp[i][j] < 0)
3339 gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n", ir->opts.anneal_temp[i][j]);
3344 /* Print out some summary information, to make sure we got it right */
3345 for (i = 0; i < nr; i++)
3347 if (ir->opts.annealing[i] != eannNO)
3349 j = groups->groups[SimulationAtomGroupType::TemperatureCoupling][i];
3350 fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
3351 *(groups->groupNames[j]), eann_names[ir->opts.annealing[i]],
3352 ir->opts.anneal_npoints[i]);
3353 fprintf(stderr, "Time (ps) Temperature (K)\n");
3354 /* All terms except the last one */
3355 for (j = 0; j < (ir->opts.anneal_npoints[i]-1); j++)
3357 fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3360 /* Finally the last one */
3361 j = ir->opts.anneal_npoints[i]-1;
3362 if (ir->opts.annealing[i] == eannSINGLE)
3364 fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3368 fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3369 if (std::fabs(ir->opts.anneal_temp[i][j]-ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS)
3371 warning_note(wi, "There is a temperature jump when your annealing loops back.\n");
3382 make_pull_groups(ir->pull, is->pull_grp, defaultIndexGroups, gnames);
3384 make_pull_coords(ir->pull);
3389 make_rotation_groups(ir->rot, is->rot_grp, defaultIndexGroups, gnames);
3392 if (ir->eSwapCoords != eswapNO)
3394 make_swap_groups(ir->swap, defaultIndexGroups, gnames);
3397 /* Make indices for IMD session */
3400 make_IMD_group(ir->imd, is->imd_grp, defaultIndexGroups, gnames);
3403 gmx::IndexGroupsAndNames defaultIndexGroupsAndNames(
3404 *defaultIndexGroups, gmx::arrayRefFromArray(gnames, defaultIndexGroups->nr));
3405 notifier.notifier_.notify(defaultIndexGroupsAndNames);
3407 auto accelerations = gmx::splitString(is->acc);
3408 auto accelerationGroupNames = gmx::splitString(is->accgrps);
3409 if (accelerationGroupNames.size() * DIM != accelerations.size())
3411 gmx_fatal(FARGS, "Invalid Acceleration input: %zu groups and %zu acc. values",
3412 accelerationGroupNames.size(), accelerations.size());
3414 do_numbering(natoms, groups, accelerationGroupNames, defaultIndexGroups, gnames,
3415 SimulationAtomGroupType::Acceleration,
3416 restnm, egrptpALL_GENREST, bVerbose, wi);
3417 nr = groups->groups[SimulationAtomGroupType::Acceleration].size();
3418 snew(ir->opts.acc, nr);
3419 ir->opts.ngacc = nr;
3421 convertRvecs(wi, accelerations, "anneal-time", ir->opts.acc);
3423 auto freezeDims = gmx::splitString(is->frdim);
3424 auto freezeGroupNames = gmx::splitString(is->freeze);
3425 if (freezeDims.size() != DIM * freezeGroupNames.size())
3427 gmx_fatal(FARGS, "Invalid Freezing input: %zu groups and %zu freeze values",
3428 freezeGroupNames.size(), freezeDims.size());
3430 do_numbering(natoms, groups, freezeGroupNames, defaultIndexGroups, gnames,
3431 SimulationAtomGroupType::Freeze,
3432 restnm, egrptpALL_GENREST, bVerbose, wi);
3433 nr = groups->groups[SimulationAtomGroupType::Freeze].size();
3434 ir->opts.ngfrz = nr;
3435 snew(ir->opts.nFreeze, nr);
3436 for (i = k = 0; (size_t(i) < freezeGroupNames.size()); i++)
3438 for (j = 0; (j < DIM); j++, k++)
3440 ir->opts.nFreeze[i][j] = static_cast<int>(gmx::equalCaseInsensitive(freezeDims[k], "Y", 1));
3441 if (!ir->opts.nFreeze[i][j])
3443 if (!gmx::equalCaseInsensitive(freezeDims[k], "N", 1))
3445 sprintf(warnbuf, "Please use Y(ES) or N(O) for freezedim only "
3446 "(not %s)", freezeDims[k].c_str());
3447 warning(wi, warn_buf);
3452 for (; (i < nr); i++)
3454 for (j = 0; (j < DIM); j++)
3456 ir->opts.nFreeze[i][j] = 0;
3460 auto energyGroupNames = gmx::splitString(is->energy);
3461 do_numbering(natoms, groups, energyGroupNames, defaultIndexGroups, gnames,
3462 SimulationAtomGroupType::EnergyOutput,
3463 restnm, egrptpALL_GENREST, bVerbose, wi);
3464 add_wall_energrps(groups, ir->nwall, symtab);
3465 ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
3466 auto vcmGroupNames = gmx::splitString(is->vcm);
3468 do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames,
3469 SimulationAtomGroupType::MassCenterVelocityRemoval,
3470 restnm, vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
3473 warning(wi, "Some atoms are not part of any center of mass motion removal group.\n"
3474 "This may lead to artifacts.\n"
3475 "In most cases one should use one group for the whole system.");
3478 /* Now we have filled the freeze struct, so we can calculate NRDF */
3479 calc_nrdf(mtop, ir, gnames);
3481 auto user1GroupNames = gmx::splitString(is->user1);
3482 do_numbering(natoms, groups, user1GroupNames, defaultIndexGroups, gnames,
3483 SimulationAtomGroupType::User1,
3484 restnm, egrptpALL_GENREST, bVerbose, wi);
3485 auto user2GroupNames = gmx::splitString(is->user2);
3486 do_numbering(natoms, groups, user2GroupNames, defaultIndexGroups, gnames,
3487 SimulationAtomGroupType::User2,
3488 restnm, egrptpALL_GENREST, bVerbose, wi);
3489 auto compressedXGroupNames = gmx::splitString(is->x_compressed_groups);
3490 do_numbering(natoms, groups, compressedXGroupNames, defaultIndexGroups, gnames,
3491 SimulationAtomGroupType::CompressedPositionOutput,
3492 restnm, egrptpONE, bVerbose, wi);
3493 auto orirefFitGroupNames = gmx::splitString(is->orirefitgrp);
3494 do_numbering(natoms, groups, orirefFitGroupNames, defaultIndexGroups, gnames,
3495 SimulationAtomGroupType::OrientationRestraintsFit,
3496 restnm, egrptpALL_GENREST, bVerbose, wi);
3498 /* QMMM input processing */
3499 auto qmGroupNames = gmx::splitString(is->QMMM);
3500 auto qmMethods = gmx::splitString(is->QMmethod);
3501 auto qmBasisSets = gmx::splitString(is->QMbasis);
3502 if (ir->eI != eiMimic)
3504 if (qmMethods.size() != qmGroupNames.size() ||
3505 qmBasisSets.size() != qmGroupNames.size())
3507 gmx_fatal(FARGS, "Invalid QMMM input: %zu groups %zu basissets"
3508 " and %zu methods\n", qmGroupNames.size(),
3509 qmBasisSets.size(), qmMethods.size());
3511 /* group rest, if any, is always MM! */
3512 do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
3513 SimulationAtomGroupType::QuantumMechanics,
3514 restnm, egrptpALL_GENREST, bVerbose, wi);
3515 nr = qmGroupNames.size(); /*atoms->grps[egcQMMM].nr;*/
3516 ir->opts.ngQM = qmGroupNames.size();
3517 snew(ir->opts.QMmethod, nr);
3518 snew(ir->opts.QMbasis, nr);
3519 for (i = 0; i < nr; i++)
3521 /* input consists of strings: RHF CASSCF PM3 .. These need to be
3522 * converted to the corresponding enum in names.c
3524 ir->opts.QMmethod[i] = search_QMstring(qmMethods[i].c_str(),
3527 ir->opts.QMbasis[i] = search_QMstring(qmBasisSets[i].c_str(),
3532 auto qmMultiplicities = gmx::splitString(is->QMmult);
3533 auto qmCharges = gmx::splitString(is->QMcharge);
3534 auto qmbSH = gmx::splitString(is->bSH);
3535 snew(ir->opts.QMmult, nr);
3536 snew(ir->opts.QMcharge, nr);
3537 snew(ir->opts.bSH, nr);
3538 convertInts(wi, qmMultiplicities, "QMmult", ir->opts.QMmult);
3539 convertInts(wi, qmCharges, "QMcharge", ir->opts.QMcharge);
3540 convertYesNos(wi, qmbSH, "bSH", ir->opts.bSH);
3542 auto CASelectrons = gmx::splitString(is->CASelectrons);
3543 auto CASorbitals = gmx::splitString(is->CASorbitals);
3544 snew(ir->opts.CASelectrons, nr);
3545 snew(ir->opts.CASorbitals, nr);
3546 convertInts(wi, CASelectrons, "CASelectrons", ir->opts.CASelectrons);
3547 convertInts(wi, CASorbitals, "CASOrbitals", ir->opts.CASorbitals);
3549 auto SAon = gmx::splitString(is->SAon);
3550 auto SAoff = gmx::splitString(is->SAoff);
3551 auto SAsteps = gmx::splitString(is->SAsteps);
3552 snew(ir->opts.SAon, nr);
3553 snew(ir->opts.SAoff, nr);
3554 snew(ir->opts.SAsteps, nr);
3555 convertInts(wi, SAon, "SAon", ir->opts.SAon);
3556 convertInts(wi, SAoff, "SAoff", ir->opts.SAoff);
3557 convertInts(wi, SAsteps, "SAsteps", ir->opts.SAsteps);
3562 if (qmGroupNames.size() > 1)
3564 gmx_fatal(FARGS, "Currently, having more than one QM group in MiMiC is not supported");
3566 /* group rest, if any, is always MM! */
3567 do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
3568 SimulationAtomGroupType::QuantumMechanics,
3569 restnm, egrptpALL_GENREST, bVerbose, wi);
3571 ir->opts.ngQM = qmGroupNames.size();
3574 /* end of QMMM input */
3578 for (auto group : gmx::keysOf(groups->groups))
3580 fprintf(stderr, "%-16s has %zu element(s):", shortName(group), groups->groups[group].size());
3581 for (const auto &entry : groups->groups[group])
3583 fprintf(stderr, " %s", *(groups->groupNames[entry]));
3585 fprintf(stderr, "\n");
3589 nr = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
3590 snew(ir->opts.egp_flags, nr*nr);
3592 bExcl = do_egp_flag(ir, groups, "energygrp-excl", is->egpexcl, EGP_EXCL);
3593 if (bExcl && ir->cutoff_scheme == ecutsVERLET)
3595 warning_error(wi, "Energy group exclusions are not (yet) implemented for the Verlet scheme");
3597 if (bExcl && EEL_FULL(ir->coulombtype))
3599 warning(wi, "Can not exclude the lattice Coulomb energy between energy groups");
3602 bTable = do_egp_flag(ir, groups, "energygrp-table", is->egptable, EGP_TABLE);
3603 if (bTable && !(ir->vdwtype == evdwUSER) &&
3604 !(ir->coulombtype == eelUSER) && !(ir->coulombtype == eelPMEUSER) &&
3605 !(ir->coulombtype == eelPMEUSERSWITCH))
3607 gmx_fatal(FARGS, "Can only have energy group pair tables in combination with user tables for VdW and/or Coulomb");
3610 /* final check before going out of scope if simulated tempering variables
3611 * need to be set to default values.
3613 if ((ir->expandedvals->nstexpanded < 0) && ir->bSimTemp)
3615 ir->expandedvals->nstexpanded = 2*static_cast<int>(ir->opts.tau_t[0]/ir->delta_t);
3616 warning(wi, gmx::formatString("the value for nstexpanded was not specified for "
3617 " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
3618 "by default, but it is recommended to set it to an explicit value!",
3619 ir->expandedvals->nstexpanded));
3621 for (i = 0; (i < defaultIndexGroups->nr); i++)
3626 done_blocka(defaultIndexGroups);
3627 sfree(defaultIndexGroups);
3633 static void check_disre(const gmx_mtop_t *mtop)
3635 if (gmx_mtop_ftype_count(mtop, F_DISRES) > 0)
3637 const gmx_ffparams_t &ffparams = mtop->ffparams;
3640 for (int i = 0; i < ffparams.numTypes(); i++)
3642 int ftype = ffparams.functype[i];
3643 if (ftype == F_DISRES)
3645 int label = ffparams.iparams[i].disres.label;
3646 if (label == old_label)
3648 fprintf(stderr, "Distance restraint index %d occurs twice\n", label);
3656 gmx_fatal(FARGS, "Found %d double distance restraint indices,\n"
3657 "probably the parameters for multiple pairs in one restraint "
3658 "are not identical\n", ndouble);
3663 static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys,
3668 gmx_mtop_ilistloop_t iloop;
3677 for (d = 0; d < DIM; d++)
3679 AbsRef[d] = (d < ndof_com(ir) ? 0 : 1);
3681 /* Check for freeze groups */
3682 for (g = 0; g < ir->opts.ngfrz; g++)
3684 for (d = 0; d < DIM; d++)
3686 if (ir->opts.nFreeze[g][d] != 0)
3694 /* Check for position restraints */
3695 iloop = gmx_mtop_ilistloop_init(sys);
3696 while (const InteractionLists *ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
3699 (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
3701 for (i = 0; i < (*ilist)[F_POSRES].size(); i += 2)
3703 pr = &sys->ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]];
3704 for (d = 0; d < DIM; d++)
3706 if (pr->posres.fcA[d] != 0)
3712 for (i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2)
3714 /* Check for flat-bottom posres */
3715 pr = &sys->ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]];
3716 if (pr->fbposres.k != 0)
3718 switch (pr->fbposres.geom)
3720 case efbposresSPHERE:
3721 AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1;
3723 case efbposresCYLINDERX:
3724 AbsRef[YY] = AbsRef[ZZ] = 1;
3726 case efbposresCYLINDERY:
3727 AbsRef[XX] = AbsRef[ZZ] = 1;
3729 case efbposresCYLINDER:
3730 /* efbposres is a synonym for efbposresCYLINDERZ for backwards compatibility */
3731 case efbposresCYLINDERZ:
3732 AbsRef[XX] = AbsRef[YY] = 1;
3734 case efbposresX: /* d=XX */
3735 case efbposresY: /* d=YY */
3736 case efbposresZ: /* d=ZZ */
3737 d = pr->fbposres.geom - efbposresX;
3741 gmx_fatal(FARGS, " Invalid geometry for flat-bottom position restraint.\n"
3742 "Expected nr between 1 and %d. Found %d\n", efbposresNR-1,
3750 return (AbsRef[XX] != 0 && AbsRef[YY] != 0 && AbsRef[ZZ] != 0);
3754 check_combination_rule_differences(const gmx_mtop_t *mtop, int state,
3755 bool *bC6ParametersWorkWithGeometricRules,
3756 bool *bC6ParametersWorkWithLBRules,
3757 bool *bLBRulesPossible)
3759 int ntypes, tpi, tpj;
3762 double c6i, c6j, c12i, c12j;
3763 double c6, c6_geometric, c6_LB;
3764 double sigmai, sigmaj, epsi, epsj;
3765 bool bCanDoLBRules, bCanDoGeometricRules;
3768 /* A tolerance of 1e-5 seems reasonable for (possibly hand-typed)
3769 * force-field floating point parameters.
3772 ptr = getenv("GMX_LJCOMB_TOL");
3776 double gmx_unused canary;
3778 if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
3780 gmx_fatal(FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
3785 *bC6ParametersWorkWithLBRules = TRUE;
3786 *bC6ParametersWorkWithGeometricRules = TRUE;
3787 bCanDoLBRules = TRUE;
3788 ntypes = mtop->ffparams.atnr;
3789 snew(typecount, ntypes);
3790 gmx_mtop_count_atomtypes(mtop, state, typecount);
3791 *bLBRulesPossible = TRUE;
3792 for (tpi = 0; tpi < ntypes; ++tpi)
3794 c6i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c6;
3795 c12i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c12;
3796 for (tpj = tpi; tpj < ntypes; ++tpj)
3798 c6j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
3799 c12j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
3800 c6 = mtop->ffparams.iparams[ntypes * tpi + tpj].lj.c6;
3801 c6_geometric = std::sqrt(c6i * c6j);
3802 if (!gmx_numzero(c6_geometric))
3804 if (!gmx_numzero(c12i) && !gmx_numzero(c12j))
3806 sigmai = gmx::sixthroot(c12i / c6i);
3807 sigmaj = gmx::sixthroot(c12j / c6j);
3808 epsi = c6i * c6i /(4.0 * c12i);
3809 epsj = c6j * c6j /(4.0 * c12j);
3810 c6_LB = 4.0 * std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj));
3814 *bLBRulesPossible = FALSE;
3815 c6_LB = c6_geometric;
3817 bCanDoLBRules = gmx_within_tol(c6_LB, c6, tol);
3822 *bC6ParametersWorkWithLBRules = FALSE;
3825 bCanDoGeometricRules = gmx_within_tol(c6_geometric, c6, tol);
3827 if (!bCanDoGeometricRules)
3829 *bC6ParametersWorkWithGeometricRules = FALSE;
3837 check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop,
3840 bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
3842 check_combination_rule_differences(mtop, 0,
3843 &bC6ParametersWorkWithGeometricRules,
3844 &bC6ParametersWorkWithLBRules,
3846 if (ir->ljpme_combination_rule == eljpmeLB)
3848 if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
3850 warning(wi, "You are using arithmetic-geometric combination rules "
3851 "in LJ-PME, but your non-bonded C6 parameters do not "
3852 "follow these rules.");
3857 if (!bC6ParametersWorkWithGeometricRules)
3859 if (ir->eDispCorr != edispcNO)
3861 warning_note(wi, "You are using geometric combination rules in "
3862 "LJ-PME, but your non-bonded C6 parameters do "
3863 "not follow these rules. "
3864 "This will introduce very small errors in the forces and energies in "
3865 "your simulations. Dispersion correction will correct total energy "
3866 "and/or pressure for isotropic systems, but not forces or surface tensions.");
3870 warning_note(wi, "You are using geometric combination rules in "
3871 "LJ-PME, but your non-bonded C6 parameters do "
3872 "not follow these rules. "
3873 "This will introduce very small errors in the forces and energies in "
3874 "your simulations. If your system is homogeneous, consider using dispersion correction "
3875 "for the total energy and pressure.");
3881 void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
3884 char err_buf[STRLEN];
3889 gmx_mtop_atomloop_block_t aloopb;
3891 char warn_buf[STRLEN];
3893 set_warning_line(wi, mdparin, -1);
3895 if (ir->cutoff_scheme == ecutsVERLET &&
3896 ir->verletbuf_tol > 0 &&
3898 ((EI_MD(ir->eI) || EI_SD(ir->eI)) &&
3899 (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
3901 /* Check if a too small Verlet buffer might potentially
3902 * cause more drift than the thermostat can couple off.
3904 /* Temperature error fraction for warning and suggestion */
3905 const real T_error_warn = 0.002;
3906 const real T_error_suggest = 0.001;
3907 /* For safety: 2 DOF per atom (typical with constraints) */
3908 const real nrdf_at = 2;
3909 real T, tau, max_T_error;
3914 for (i = 0; i < ir->opts.ngtc; i++)
3916 T = std::max(T, ir->opts.ref_t[i]);
3917 tau = std::max(tau, ir->opts.tau_t[i]);
3921 /* This is a worst case estimate of the temperature error,
3922 * assuming perfect buffer estimation and no cancelation
3923 * of errors. The factor 0.5 is because energy distributes
3924 * equally over Ekin and Epot.
3926 max_T_error = 0.5*tau*ir->verletbuf_tol/(nrdf_at*BOLTZ*T);
3927 if (max_T_error > T_error_warn)
3929 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.",
3930 ir->verletbuf_tol, T, tau,
3932 100*T_error_suggest,
3933 ir->verletbuf_tol*T_error_suggest/max_T_error);
3934 warning(wi, warn_buf);
3939 if (ETC_ANDERSEN(ir->etc))
3943 for (i = 0; i < ir->opts.ngtc; i++)
3945 sprintf(err_buf, "all tau_t must currently be equal using Andersen temperature control, violated for group %d", i);
3946 CHECK(ir->opts.tau_t[0] != ir->opts.tau_t[i]);
3947 sprintf(err_buf, "all tau_t must be positive using Andersen temperature control, tau_t[%d]=%10.6f",
3948 i, ir->opts.tau_t[i]);
3949 CHECK(ir->opts.tau_t[i] < 0);
3952 if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
3954 for (i = 0; i < ir->opts.ngtc; i++)
3956 int nsteps = gmx::roundToInt(ir->opts.tau_t[i]/ir->delta_t);
3957 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);
3958 CHECK(nsteps % ir->nstcomm != 0);
3963 if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD &&
3964 ir->comm_mode == ecmNO &&
3965 !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) &&
3966 !ETC_ANDERSEN(ir->etc))
3968 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");
3971 if (ir->epc == epcPARRINELLORAHMAN &&
3972 ir->etc == etcNOSEHOOVER)
3975 for (int g = 0; g < ir->opts.ngtc; g++)
3977 tau_t_max = std::max(tau_t_max, ir->opts.tau_t[g]);
3979 if (ir->tau_p < 1.9*tau_t_max)
3981 std::string message =
3982 gmx::formatString("With %s T-coupling and %s p-coupling, "
3983 "%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
3984 etcoupl_names[ir->etc],
3985 epcoupl_names[ir->epc],
3987 "tau-t", tau_t_max);
3988 warning(wi, message.c_str());
3992 /* Check for pressure coupling with absolute position restraints */
3993 if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
3995 absolute_reference(ir, sys, TRUE, AbsRef);
3997 for (m = 0; m < DIM; m++)
3999 if (AbsRef[m] && norm2(ir->compress[m]) > 0)
4001 warning(wi, "You are using pressure coupling with absolute position restraints, this will give artifacts. Use the refcoord_scaling option.");
4009 aloopb = gmx_mtop_atomloop_block_init(sys);
4011 while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol))
4013 if (atom->q != 0 || atom->qB != 0)
4021 if (EEL_FULL(ir->coulombtype))
4024 "You are using full electrostatics treatment %s for a system without charges.\n"
4025 "This costs a lot of performance for just processing zeros, consider using %s instead.\n",
4026 EELTYPE(ir->coulombtype), EELTYPE(eelCUT));
4027 warning(wi, err_buf);
4032 if (ir->coulombtype == eelCUT && ir->rcoulomb > 0)
4035 "You are using a plain Coulomb cut-off, which might produce artifacts.\n"
4036 "You might want to consider using %s electrostatics.\n",
4038 warning_note(wi, err_buf);
4042 /* Check if combination rules used in LJ-PME are the same as in the force field */
4043 if (EVDW_PME(ir->vdwtype))
4045 check_combination_rules(ir, sys, wi);
4048 /* Generalized reaction field */
4049 if (ir->coulombtype == eelGRF_NOTUSED)
4051 warning_error(wi, "Generalized reaction-field electrostatics is no longer supported. "
4052 "You can use normal reaction-field instead and compute the reaction-field constant by hand.");
4056 for (int i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
4058 for (m = 0; (m < DIM); m++)
4060 if (fabs(ir->opts.acc[i][m]) > 1e-6)
4069 snew(mgrp, sys->groups.groups[SimulationAtomGroupType::Acceleration].size());
4070 for (const AtomProxy atomP : AtomRange(*sys))
4072 const t_atom &local = atomP.atom();
4073 int i = atomP.globalAtomNumber();
4074 mgrp[getGroupType(sys->groups, SimulationAtomGroupType::Acceleration, i)] += local.m;
4077 for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
4079 for (m = 0; (m < DIM); m++)
4081 acc[m] += ir->opts.acc[i][m]*mgrp[i];
4085 for (m = 0; (m < DIM); m++)
4087 if (fabs(acc[m]) > 1e-6)
4089 const char *dim[DIM] = { "X", "Y", "Z" };
4091 "Net Acceleration in %s direction, will %s be corrected\n",
4092 dim[m], ir->nstcomm != 0 ? "" : "not");
4093 if (ir->nstcomm != 0 && m < ndof_com(ir))
4096 for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
4098 ir->opts.acc[i][m] -= acc[m];
4106 if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0 &&
4107 !gmx_within_tol(sys->ffparams.reppow, 12.0, 10*GMX_DOUBLE_EPS))
4109 gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12");
4117 for (i = 0; i < ir->pull->ncoord && !bWarned; i++)
4119 if (ir->pull->coord[i].group[0] == 0 ||
4120 ir->pull->coord[i].group[1] == 0)
4122 absolute_reference(ir, sys, FALSE, AbsRef);
4123 for (m = 0; m < DIM; m++)
4125 if (ir->pull->coord[i].dim[m] && !AbsRef[m])
4127 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.");
4135 for (i = 0; i < 3; i++)
4137 for (m = 0; m <= i; m++)
4139 if ((ir->epc != epcNO && ir->compress[i][m] != 0) ||
4140 ir->deform[i][m] != 0)
4142 for (c = 0; c < ir->pull->ncoord; c++)
4144 if (ir->pull->coord[c].eGeom == epullgDIRPBC &&
4145 ir->pull->coord[c].vec[m] != 0)
4147 gmx_fatal(FARGS, "Can not have dynamic box while using pull geometry '%s' (dim %c)", EPULLGEOM(ir->pull->coord[c].eGeom), 'x'+m);
4158 void double_check(t_inputrec *ir, matrix box,
4159 bool bHasNormalConstraints,
4160 bool bHasAnyConstraints,
4163 char warn_buf[STRLEN];
4166 ptr = check_box(ir->ePBC, box);
4169 warning_error(wi, ptr);
4172 if (bHasNormalConstraints && ir->eConstrAlg == econtSHAKE)
4174 if (ir->shake_tol <= 0.0)
4176 sprintf(warn_buf, "ERROR: shake-tol must be > 0 instead of %g\n",
4178 warning_error(wi, warn_buf);
4182 if ( (ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
4184 /* If we have Lincs constraints: */
4185 if (ir->eI == eiMD && ir->etc == etcNO &&
4186 ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
4188 sprintf(warn_buf, "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
4189 warning_note(wi, warn_buf);
4192 if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8))
4194 sprintf(warn_buf, "For accurate %s with LINCS constraints, lincs-order should be 8 or more.", ei_names[ir->eI]);
4195 warning_note(wi, warn_buf);
4197 if (ir->epc == epcMTTK)
4199 warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
4203 if (bHasAnyConstraints && ir->epc == epcMTTK)
4205 warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
4208 if (ir->LincsWarnAngle > 90.0)
4210 sprintf(warn_buf, "lincs-warnangle can not be larger than 90 degrees, setting it to 90.\n");
4211 warning(wi, warn_buf);
4212 ir->LincsWarnAngle = 90.0;
4215 if (ir->ePBC != epbcNONE)
4217 if (ir->nstlist == 0)
4219 warning(wi, "With nstlist=0 atoms are only put into the box at step 0, therefore drifting atoms might cause the simulation to crash.");
4221 if (gmx::square(ir->rlist) >= max_cutoff2(ir->ePBC, box))
4223 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");
4224 warning_error(wi, warn_buf);
4229 void check_chargegroup_radii(const gmx_mtop_t *mtop, const t_inputrec *ir,
4233 real rvdw1, rvdw2, rcoul1, rcoul2;
4234 char warn_buf[STRLEN];
4236 calc_chargegroup_radii(mtop, x, &rvdw1, &rvdw2, &rcoul1, &rcoul2);
4240 printf("Largest charge group radii for Van der Waals: %5.3f, %5.3f nm\n",
4245 printf("Largest charge group radii for Coulomb: %5.3f, %5.3f nm\n",
4251 if (rvdw1 + rvdw2 > ir->rlist ||
4252 rcoul1 + rcoul2 > ir->rlist)
4255 "The sum of the two largest charge group radii (%f) "
4256 "is larger than rlist (%f)\n",
4257 std::max(rvdw1+rvdw2, rcoul1+rcoul2), ir->rlist);
4258 warning(wi, warn_buf);
4262 /* Here we do not use the zero at cut-off macro,
4263 * since user defined interactions might purposely
4264 * not be zero at the cut-off.
4266 if (ir_vdw_is_zero_at_cutoff(ir) &&
4267 rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
4269 sprintf(warn_buf, "The sum of the two largest charge group "
4270 "radii (%f) is larger than rlist (%f) - rvdw (%f).\n"
4271 "With exact cut-offs, better performance can be "
4272 "obtained with cutoff-scheme = %s, because it "
4273 "does not use charge groups at all.",
4275 ir->rlist, ir->rvdw,
4276 ecutscheme_names[ecutsVERLET]);
4279 warning(wi, warn_buf);
4283 warning_note(wi, warn_buf);
4286 if (ir_coulomb_is_zero_at_cutoff(ir) &&
4287 rcoul1 + rcoul2 > ir->rlist - ir->rcoulomb)
4289 sprintf(warn_buf, "The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rcoulomb (%f).\n"
4290 "With exact cut-offs, better performance can be obtained with cutoff-scheme = %s, because it does not use charge groups at all.",
4292 ir->rlist, ir->rcoulomb,
4293 ecutscheme_names[ecutsVERLET]);
4296 warning(wi, warn_buf);
4300 warning_note(wi, warn_buf);