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, const gmx::MdModulesNotifier &mdModulesNotifier,
242 t_inputrec *ir, t_gromppopts *opts, warninp_t wi)
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);
531 // Inquire all MdModules, if their parameters match with the energy
532 // calculation frequency
533 gmx::EnergyCalculationFrequencyErrors energyCalculationFrequencyErrors(ir->nstcalcenergy);
534 mdModulesNotifier.notifier_.notify(&energyCalculationFrequencyErrors);
536 // Emit all errors from the energy calculation frequency checks
537 for (const std::string &energyFrequencyErrorMessage : energyCalculationFrequencyErrors.errorMessages())
539 warning_error(wi, energyFrequencyErrorMessage);
543 if (ir->nsteps == 0 && !ir->bContinuation)
545 warning_note(wi, "For a correct single-point energy evaluation with nsteps = 0, use continuation = yes to avoid constraining the input coordinates.");
549 if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
550 ir->bContinuation && ir->ld_seed != -1)
552 warning_note(wi, "You are doing a continuation with SD or BD, make sure that ld_seed is different from the previous run (using ld_seed=-1 will ensure this)");
558 sprintf(err_buf, "TPI only works with pbc = %s", epbc_names[epbcXYZ]);
559 CHECK(ir->ePBC != epbcXYZ);
560 sprintf(err_buf, "with TPI nstlist should be larger than zero");
561 CHECK(ir->nstlist <= 0);
562 sprintf(err_buf, "TPI does not work with full electrostatics other than PME");
563 CHECK(EEL_FULL(ir->coulombtype) && !EEL_PME(ir->coulombtype));
567 if ( (opts->nshake > 0) && (opts->bMorse) )
570 "Using morse bond-potentials while constraining bonds is useless");
571 warning(wi, warn_buf);
574 if ((EI_SD(ir->eI) || ir->eI == eiBD) &&
575 ir->bContinuation && ir->ld_seed != -1)
577 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)");
579 /* verify simulated tempering options */
583 bool bAllTempZero = TRUE;
584 for (i = 0; i < fep->n_lambda; i++)
586 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]);
587 CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
588 if (fep->all_lambda[efptTEMPERATURE][i] > 0)
590 bAllTempZero = FALSE;
593 sprintf(err_buf, "if simulated tempering is on, temperature-lambdas may not be all zero");
594 CHECK(bAllTempZero == TRUE);
596 sprintf(err_buf, "Simulated tempering is currently only compatible with md-vv");
597 CHECK(ir->eI != eiVV);
599 /* check compatability of the temperature coupling with simulated tempering */
601 if (ir->etc == etcNOSEHOOVER)
603 sprintf(warn_buf, "Nose-Hoover based temperature control such as [%s] my not be entirelyconsistent with simulated tempering", etcoupl_names[ir->etc]);
604 warning_note(wi, warn_buf);
607 /* check that the temperatures make sense */
609 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);
610 CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low);
612 sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_high);
613 CHECK(ir->simtempvals->simtemp_high <= 0);
615 sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_low);
616 CHECK(ir->simtempvals->simtemp_low <= 0);
619 /* verify free energy options */
621 if (ir->efep != efepNO)
624 sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2",
626 CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2);
628 sprintf(err_buf, "The soft-core sc-r-power is %d and can only be 6 or 48",
629 static_cast<int>(fep->sc_r_power));
630 CHECK(fep->sc_alpha != 0 && fep->sc_r_power != 6.0 && fep->sc_r_power != 48.0);
632 sprintf(err_buf, "Can't use positive delta-lambda (%g) if initial state/lambda does not start at zero", fep->delta_lambda);
633 CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0)));
635 sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations", fep->delta_lambda);
636 CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
638 sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)");
639 CHECK(!(EI_VV(ir->eI)) && (ir->efep == efepEXPANDED));
641 sprintf(err_buf, "Free-energy not implemented for Ewald");
642 CHECK(ir->coulombtype == eelEWALD);
644 /* check validty of lambda inputs */
645 if (fep->n_lambda == 0)
647 /* Clear output in case of no states:*/
648 sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state);
649 CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0));
653 sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d", fep->init_fep_state, fep->n_lambda-1);
654 CHECK((fep->init_fep_state >= fep->n_lambda));
657 sprintf(err_buf, "Lambda state must be set, either with init-lambda-state or with init-lambda");
658 CHECK((fep->init_fep_state < 0) && (fep->init_lambda < 0));
660 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",
661 fep->init_lambda, fep->init_fep_state);
662 CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
666 if ((fep->init_lambda >= 0) && (fep->delta_lambda == 0))
670 for (i = 0; i < efptNR; i++)
672 if (fep->separate_dvdl[i])
677 if (n_lambda_terms > 1)
679 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.");
680 warning(wi, warn_buf);
683 if (n_lambda_terms < 2 && fep->n_lambda > 0)
686 "init-lambda is deprecated for setting lambda state (except for slow growth). Use init-lambda-state instead.");
690 for (j = 0; j < efptNR; j++)
692 for (i = 0; i < fep->n_lambda; i++)
694 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]);
695 CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
699 if ((fep->sc_alpha > 0) && (!fep->bScCoul))
701 for (i = 0; i < fep->n_lambda; i++)
703 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],
704 fep->all_lambda[efptCOUL][i]);
705 CHECK((fep->sc_alpha > 0) &&
706 (((fep->all_lambda[efptCOUL][i] > 0.0) &&
707 (fep->all_lambda[efptCOUL][i] < 1.0)) &&
708 ((fep->all_lambda[efptVDW][i] > 0.0) &&
709 (fep->all_lambda[efptVDW][i] < 1.0))));
713 if ((fep->bScCoul) && (EEL_PME(ir->coulombtype)))
715 real sigma, lambda, r_sc;
718 /* Maximum estimate for A and B charges equal with lambda power 1 */
720 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);
721 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.",
723 sigma, lambda, r_sc - 1.0, ir->ewald_rtol);
724 warning_note(wi, warn_buf);
727 /* Free Energy Checks -- In an ideal world, slow growth and FEP would
728 be treated differently, but that's the next step */
730 for (i = 0; i < efptNR; i++)
732 for (j = 0; j < fep->n_lambda; j++)
734 sprintf(err_buf, "%s[%d] must be between 0 and 1", efpt_names[i], j);
735 CHECK((fep->all_lambda[i][j] < 0) || (fep->all_lambda[i][j] > 1));
740 if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
744 /* checking equilibration of weights inputs for validity */
746 sprintf(err_buf, "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal to %s",
747 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
748 CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
750 sprintf(err_buf, "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to %s",
751 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
752 CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
754 sprintf(err_buf, "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
755 expand->equil_steps, elmceq_names[elmceqSTEPS]);
756 CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
758 sprintf(err_buf, "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
759 expand->equil_samples, elmceq_names[elmceqWLDELTA]);
760 CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
762 sprintf(err_buf, "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
763 expand->equil_ratio, elmceq_names[elmceqRATIO]);
764 CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
766 sprintf(err_buf, "weight-equil-number-all-lambda (%d) must be a positive integer if lmc-weights-equil=%s",
767 expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]);
768 CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
770 sprintf(err_buf, "weight-equil-number-samples (%d) must be a positive integer if lmc-weights-equil=%s",
771 expand->equil_samples, elmceq_names[elmceqSAMPLES]);
772 CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
774 sprintf(err_buf, "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
775 expand->equil_steps, elmceq_names[elmceqSTEPS]);
776 CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
778 sprintf(err_buf, "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
779 expand->equil_wl_delta, elmceq_names[elmceqWLDELTA]);
780 CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
782 sprintf(err_buf, "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
783 expand->equil_ratio, elmceq_names[elmceqRATIO]);
784 CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
786 sprintf(err_buf, "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
787 elmceq_names[elmceqWLDELTA], elamstats_names[elamstatsWL], elamstats_names[elamstatsWWL]);
788 CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
790 sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
791 CHECK((expand->lmc_repeats <= 0));
792 sprintf(err_buf, "minimum-var-min (%d) must be greater than 0", expand->minvarmin);
793 CHECK((expand->minvarmin <= 0));
794 sprintf(err_buf, "weight-c-range (%d) must be greater or equal to 0", expand->c_range);
795 CHECK((expand->c_range < 0));
796 sprintf(err_buf, "init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != 'no'",
797 fep->init_fep_state, expand->lmc_forced_nstart);
798 CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0) && (expand->elmcmove != elmcmoveNO));
799 sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
800 CHECK((expand->lmc_forced_nstart < 0));
801 sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)", fep->init_fep_state);
802 CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda));
804 sprintf(err_buf, "init-wl-delta (%f) must be greater than or equal to 0", expand->init_wl_delta);
805 CHECK((expand->init_wl_delta < 0));
806 sprintf(err_buf, "wl-ratio (%f) must be between 0 and 1", expand->wl_ratio);
807 CHECK((expand->wl_ratio <= 0) || (expand->wl_ratio >= 1));
808 sprintf(err_buf, "wl-scale (%f) must be between 0 and 1", expand->wl_scale);
809 CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1));
811 /* if there is no temperature control, we need to specify an MC temperature */
812 if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO) && (expand->mc_temp <= 0.0))
814 sprintf(err_buf, "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set to a positive number");
815 warning_error(wi, err_buf);
817 if (expand->nstTij > 0)
819 sprintf(err_buf, "nstlog must be non-zero");
820 CHECK(ir->nstlog == 0);
821 // Avoid modulus by zero in the case that already triggered an error exit.
824 sprintf(err_buf, "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)",
825 expand->nstTij, ir->nstlog);
826 CHECK((expand->nstTij % ir->nstlog) != 0);
832 sprintf(err_buf, "walls only work with pbc=%s", epbc_names[epbcXY]);
833 CHECK(ir->nwall && ir->ePBC != epbcXY);
836 if (ir->ePBC != epbcXYZ && ir->nwall != 2)
838 if (ir->ePBC == epbcNONE)
840 if (ir->epc != epcNO)
842 warning(wi, "Turning off pressure coupling for vacuum system");
848 sprintf(err_buf, "Can not have pressure coupling with pbc=%s",
849 epbc_names[ir->ePBC]);
850 CHECK(ir->epc != epcNO);
852 sprintf(err_buf, "Can not have Ewald with pbc=%s", epbc_names[ir->ePBC]);
853 CHECK(EEL_FULL(ir->coulombtype));
855 sprintf(err_buf, "Can not have dispersion correction with pbc=%s",
856 epbc_names[ir->ePBC]);
857 CHECK(ir->eDispCorr != edispcNO);
860 if (ir->rlist == 0.0)
862 sprintf(err_buf, "can only have neighborlist cut-off zero (=infinite)\n"
863 "with coulombtype = %s or coulombtype = %s\n"
864 "without periodic boundary conditions (pbc = %s) and\n"
865 "rcoulomb and rvdw set to zero",
866 eel_names[eelCUT], eel_names[eelUSER], epbc_names[epbcNONE]);
867 CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER)) ||
868 (ir->ePBC != epbcNONE) ||
869 (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0));
873 warning_note(wi, "Simulating without cut-offs can be (slightly) faster with nstlist=0, nstype=simple and only one MPI rank");
878 if (ir->nstcomm == 0)
880 // TODO Change this behaviour. There should be exactly one way
881 // to turn off an algorithm.
882 ir->comm_mode = ecmNO;
884 if (ir->comm_mode != ecmNO)
888 // TODO Such input was once valid. Now that we've been
889 // helpful for a few years, we should reject such input,
890 // lest we have to support every historical decision
892 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");
893 ir->nstcomm = abs(ir->nstcomm);
896 if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy)
898 warning_note(wi, "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting nstcomm to nstcalcenergy");
899 ir->nstcomm = ir->nstcalcenergy;
902 if (ir->comm_mode == ecmANGULAR)
904 sprintf(err_buf, "Can not remove the rotation around the center of mass with periodic molecules");
905 CHECK(ir->bPeriodicMols);
906 if (ir->ePBC != epbcNONE)
908 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.");
913 if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->ePBC == epbcNONE && ir->comm_mode != ecmANGULAR)
915 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]);
916 warning_note(wi, warn_buf);
919 /* TEMPERATURE COUPLING */
920 if (ir->etc == etcYES)
922 ir->etc = etcBERENDSEN;
923 warning_note(wi, "Old option for temperature coupling given: "
924 "changing \"yes\" to \"Berendsen\"\n");
927 if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
929 if (ir->opts.nhchainlength < 1)
931 sprintf(warn_buf, "number of Nose-Hoover chains (currently %d) cannot be less than 1,reset to 1\n", ir->opts.nhchainlength);
932 ir->opts.nhchainlength = 1;
933 warning(wi, warn_buf);
936 if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
938 warning_note(wi, "leapfrog does not yet support Nose-Hoover chains, nhchainlength reset to 1");
939 ir->opts.nhchainlength = 1;
944 ir->opts.nhchainlength = 0;
947 if (ir->eI == eiVVAK)
949 sprintf(err_buf, "%s implemented primarily for validation, and requires nsttcouple = 1 and nstpcouple = 1.",
951 CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1));
954 if (ETC_ANDERSEN(ir->etc))
956 sprintf(err_buf, "%s temperature control not supported for integrator %s.", etcoupl_names[ir->etc], ei_names[ir->eI]);
957 CHECK(!(EI_VV(ir->eI)));
959 if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
961 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]);
962 warning_note(wi, warn_buf);
965 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]);
966 CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
969 if (ir->etc == etcBERENDSEN)
971 sprintf(warn_buf, "The %s thermostat does not generate the correct kinetic energy distribution. You might want to consider using the %s thermostat.",
972 ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE));
973 warning_note(wi, warn_buf);
976 if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc))
977 && ir->epc == epcBERENDSEN)
979 sprintf(warn_buf, "Using Berendsen pressure coupling invalidates the "
980 "true ensemble for the thermostat");
981 warning(wi, warn_buf);
984 /* PRESSURE COUPLING */
985 if (ir->epc == epcISOTROPIC)
987 ir->epc = epcBERENDSEN;
988 warning_note(wi, "Old option for pressure coupling given: "
989 "changing \"Isotropic\" to \"Berendsen\"\n");
992 if (ir->epc != epcNO)
994 dt_pcoupl = ir->nstpcouple*ir->delta_t;
996 sprintf(err_buf, "tau-p must be > 0 instead of %g\n", ir->tau_p);
997 CHECK(ir->tau_p <= 0);
999 if (ir->tau_p/dt_pcoupl < pcouple_min_integration_steps(ir->epc) - 10*GMX_REAL_EPS)
1001 sprintf(warn_buf, "For proper integration of the %s barostat, tau-p (%g) should be at least %d times larger than nstpcouple*dt (%g)",
1002 EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl);
1003 warning(wi, warn_buf);
1006 sprintf(err_buf, "compressibility must be > 0 when using pressure"
1007 " coupling %s\n", EPCOUPLTYPE(ir->epc));
1008 CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 ||
1009 ir->compress[ZZ][ZZ] < 0 ||
1010 (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 &&
1011 ir->compress[ZZ][XX] <= 0 && ir->compress[ZZ][YY] <= 0));
1013 if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
1016 "You are generating velocities so I am assuming you "
1017 "are equilibrating a system. You are using "
1018 "%s pressure coupling, but this can be "
1019 "unstable for equilibration. If your system crashes, try "
1020 "equilibrating first with Berendsen pressure coupling. If "
1021 "you are not equilibrating the system, you can probably "
1022 "ignore this warning.",
1023 epcoupl_names[ir->epc]);
1024 warning(wi, warn_buf);
1030 if (ir->epc > epcNO)
1032 if ((ir->epc != epcBERENDSEN) && (ir->epc != epcMTTK))
1034 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.");
1040 if (ir->epc == epcMTTK)
1042 warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
1046 /* ELECTROSTATICS */
1047 /* More checks are in triple check (grompp.c) */
1049 if (ir->coulombtype == eelSWITCH)
1051 sprintf(warn_buf, "coulombtype = %s is only for testing purposes and can lead to serious "
1052 "artifacts, advice: use coulombtype = %s",
1053 eel_names[ir->coulombtype],
1054 eel_names[eelRF_ZERO]);
1055 warning(wi, warn_buf);
1058 if (EEL_RF(ir->coulombtype) && ir->epsilon_rf == 1 && ir->epsilon_r != 1)
1060 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);
1061 warning(wi, warn_buf);
1062 ir->epsilon_rf = ir->epsilon_r;
1063 ir->epsilon_r = 1.0;
1066 if (ir->epsilon_r == 0)
1069 "It is pointless to use long-range electrostatics with infinite relative permittivity."
1070 "Since you are effectively turning of electrostatics, a plain cutoff will be much faster.");
1071 CHECK(EEL_FULL(ir->coulombtype));
1074 if (getenv("GMX_DO_GALACTIC_DYNAMICS") == nullptr)
1076 sprintf(err_buf, "epsilon-r must be >= 0 instead of %g\n", ir->epsilon_r);
1077 CHECK(ir->epsilon_r < 0);
1080 if (EEL_RF(ir->coulombtype))
1082 /* reaction field (at the cut-off) */
1084 if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0)
1086 sprintf(warn_buf, "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0",
1087 eel_names[ir->coulombtype]);
1088 warning(wi, warn_buf);
1089 ir->epsilon_rf = 0.0;
1092 sprintf(err_buf, "epsilon-rf must be >= epsilon-r");
1093 CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) ||
1094 (ir->epsilon_r == 0));
1095 if (ir->epsilon_rf == ir->epsilon_r)
1097 sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense",
1098 eel_names[ir->coulombtype]);
1099 warning(wi, warn_buf);
1102 /* Allow rlist>rcoulomb for tabulated long range stuff. This just
1103 * means the interaction is zero outside rcoulomb, but it helps to
1104 * provide accurate energy conservation.
1106 if (ir_coulomb_might_be_zero_at_cutoff(ir))
1108 if (ir_coulomb_switched(ir))
1111 "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the potential modifier options!",
1112 eel_names[ir->coulombtype]);
1113 CHECK(ir->rcoulomb_switch >= ir->rcoulomb);
1117 if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT)
1120 "Explicit switch/shift coulomb interactions cannot be used in combination with a secondary coulomb-modifier.");
1121 CHECK( ir->coulomb_modifier != eintmodNONE);
1123 if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1126 "Explicit switch/shift vdw interactions cannot be used in combination with a secondary vdw-modifier.");
1127 CHECK( ir->vdw_modifier != eintmodNONE);
1130 if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT ||
1131 ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
1134 "The switch/shift interaction settings are just for compatibility; you will get better "
1135 "performance from applying potential modifiers to your interactions!\n");
1136 warning_note(wi, warn_buf);
1139 if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH)
1141 if (ir->rcoulomb_switch/ir->rcoulomb < 0.9499)
1143 real percentage = 100*(ir->rcoulomb-ir->rcoulomb_switch)/ir->rcoulomb;
1144 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.",
1145 percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol);
1146 warning(wi, warn_buf);
1150 if (ir->vdwtype == evdwSWITCH || ir->vdw_modifier == eintmodPOTSWITCH)
1152 if (ir->rvdw_switch == 0)
1154 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.");
1155 warning(wi, warn_buf);
1159 if (EEL_FULL(ir->coulombtype))
1161 if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER ||
1162 ir->coulombtype == eelPMEUSERSWITCH)
1164 sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist",
1165 eel_names[ir->coulombtype]);
1166 CHECK(ir->rcoulomb > ir->rlist);
1170 if (EEL_PME(ir->coulombtype) || EVDW_PME(ir->vdwtype))
1172 // TODO: Move these checks into the ewald module with the options class
1174 int orderMax = (ir->coulombtype == eelP3M_AD ? 8 : 12);
1176 if (ir->pme_order < orderMin || ir->pme_order > orderMax)
1178 sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d", eel_names[ir->coulombtype], orderMin, orderMax);
1179 warning_error(wi, warn_buf);
1183 if (ir->nwall == 2 && EEL_FULL(ir->coulombtype))
1185 if (ir->ewald_geometry == eewg3D)
1187 sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s",
1188 epbc_names[ir->ePBC], eewg_names[eewg3DC]);
1189 warning(wi, warn_buf);
1191 /* This check avoids extra pbc coding for exclusion corrections */
1192 sprintf(err_buf, "wall-ewald-zfac should be >= 2");
1193 CHECK(ir->wall_ewald_zfac < 2);
1195 if ((ir->ewald_geometry == eewg3DC) && (ir->ePBC != epbcXY) &&
1196 EEL_FULL(ir->coulombtype))
1198 sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s",
1199 eel_names[ir->coulombtype], eewg_names[eewg3DC], epbc_names[epbcXY]);
1200 warning(wi, warn_buf);
1202 if ((ir->epsilon_surface != 0) && EEL_FULL(ir->coulombtype))
1204 sprintf(err_buf, "Cannot have periodic molecules with epsilon_surface > 0");
1205 CHECK(ir->bPeriodicMols);
1206 sprintf(warn_buf, "With epsilon_surface > 0 all molecules should be neutral.");
1207 warning_note(wi, warn_buf);
1209 "With epsilon_surface > 0 you can only use domain decomposition "
1210 "when there are only small molecules with all bonds constrained (mdrun will check for this).");
1211 warning_note(wi, warn_buf);
1214 if (ir_vdw_switched(ir))
1216 sprintf(err_buf, "With switched vdw forces or potentials, rvdw-switch must be < rvdw");
1217 CHECK(ir->rvdw_switch >= ir->rvdw);
1219 if (ir->rvdw_switch < 0.5*ir->rvdw)
1221 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.",
1222 ir->rvdw_switch, ir->rvdw);
1223 warning_note(wi, warn_buf);
1227 if (ir->vdwtype == evdwPME)
1229 if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
1231 sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s",
1232 evdw_names[ir->vdwtype],
1233 eintmod_names[eintmodPOTSHIFT],
1234 eintmod_names[eintmodNONE]);
1235 warning_error(wi, err_buf);
1239 if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO)
1241 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.");
1244 if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT)
1247 warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off.");
1250 if (ir->eI == eiLBFGS && ir->nbfgscorr <= 0)
1252 warning(wi, "Using L-BFGS with nbfgscorr<=0 just gets you steepest descent.");
1255 /* IMPLICIT SOLVENT */
1256 if (ir->coulombtype == eelGB_NOTUSED)
1258 sprintf(warn_buf, "Invalid option %s for coulombtype",
1259 eel_names[ir->coulombtype]);
1260 warning_error(wi, warn_buf);
1265 if (ir->cutoff_scheme != ecutsGROUP)
1267 warning_error(wi, "QMMM is currently only supported with cutoff-scheme=group");
1269 if (!EI_DYNAMICS(ir->eI))
1272 sprintf(buf, "QMMM is only supported with dynamics, not with integrator %s", ei_names[ir->eI]);
1273 warning_error(wi, buf);
1279 gmx_fatal(FARGS, "AdResS simulations are no longer supported");
1283 /* interpret a number of doubles from a string and put them in an array,
1284 after allocating space for them.
1285 str = the input string
1286 n = the (pre-allocated) number of doubles read
1287 r = the output array of doubles. */
1288 static void parse_n_real(char *str, int *n, real **r, warninp_t wi)
1290 auto values = gmx::splitString(str);
1294 for (int i = 0; i < *n; i++)
1298 (*r)[i] = gmx::fromString<real>(values[i]);
1300 catch (gmx::GromacsException &)
1302 warning_error(wi, "Invalid value " + values[i] + " in string in mdp file. Expected a real number.");
1308 static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi)
1311 int i, j, max_n_lambda, nweights, nfep[efptNR];
1312 t_lambda *fep = ir->fepvals;
1313 t_expanded *expand = ir->expandedvals;
1314 real **count_fep_lambdas;
1315 bool bOneLambda = TRUE;
1317 snew(count_fep_lambdas, efptNR);
1319 /* FEP input processing */
1320 /* first, identify the number of lambda values for each type.
1321 All that are nonzero must have the same number */
1323 for (i = 0; i < efptNR; i++)
1325 parse_n_real(fep_lambda[i], &(nfep[i]), &(count_fep_lambdas[i]), wi);
1328 /* now, determine the number of components. All must be either zero, or equal. */
1331 for (i = 0; i < efptNR; i++)
1333 if (nfep[i] > max_n_lambda)
1335 max_n_lambda = nfep[i]; /* here's a nonzero one. All of them
1336 must have the same number if its not zero.*/
1341 for (i = 0; i < efptNR; i++)
1345 ir->fepvals->separate_dvdl[i] = FALSE;
1347 else if (nfep[i] == max_n_lambda)
1349 if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute the derivative with
1350 respect to the temperature currently */
1352 ir->fepvals->separate_dvdl[i] = TRUE;
1357 gmx_fatal(FARGS, "Number of lambdas (%d) for FEP type %s not equal to number of other types (%d)",
1358 nfep[i], efpt_names[i], max_n_lambda);
1361 /* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
1362 ir->fepvals->separate_dvdl[efptTEMPERATURE] = FALSE;
1364 /* the number of lambdas is the number we've read in, which is either zero
1365 or the same for all */
1366 fep->n_lambda = max_n_lambda;
1368 /* allocate space for the array of lambda values */
1369 snew(fep->all_lambda, efptNR);
1370 /* if init_lambda is defined, we need to set lambda */
1371 if ((fep->init_lambda > 0) && (fep->n_lambda == 0))
1373 ir->fepvals->separate_dvdl[efptFEP] = TRUE;
1375 /* otherwise allocate the space for all of the lambdas, and transfer the data */
1376 for (i = 0; i < efptNR; i++)
1378 snew(fep->all_lambda[i], fep->n_lambda);
1379 if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays
1382 for (j = 0; j < fep->n_lambda; j++)
1384 fep->all_lambda[i][j] = static_cast<double>(count_fep_lambdas[i][j]);
1386 sfree(count_fep_lambdas[i]);
1389 sfree(count_fep_lambdas);
1391 /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for internal
1392 bookkeeping -- for now, init_lambda */
1394 if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
1396 for (i = 0; i < fep->n_lambda; i++)
1398 fep->all_lambda[efptFEP][i] = fep->init_lambda;
1402 /* check to see if only a single component lambda is defined, and soft core is defined.
1403 In this case, turn on coulomb soft core */
1405 if (max_n_lambda == 0)
1411 for (i = 0; i < efptNR; i++)
1413 if ((nfep[i] != 0) && (i != efptFEP))
1419 if ((bOneLambda) && (fep->sc_alpha > 0))
1421 fep->bScCoul = TRUE;
1424 /* Fill in the others with the efptFEP if they are not explicitly
1425 specified (i.e. nfep[i] == 0). This means if fep is not defined,
1426 they are all zero. */
1428 for (i = 0; i < efptNR; i++)
1430 if ((nfep[i] == 0) && (i != efptFEP))
1432 for (j = 0; j < fep->n_lambda; j++)
1434 fep->all_lambda[i][j] = fep->all_lambda[efptFEP][j];
1440 /* make it easier if sc_r_power = 48 by increasing it to the 4th power, to be in the right scale. */
1441 if (fep->sc_r_power == 48)
1443 if (fep->sc_alpha > 0.1)
1445 gmx_fatal(FARGS, "sc_alpha (%f) for sc_r_power = 48 should usually be between 0.001 and 0.004", fep->sc_alpha);
1449 /* now read in the weights */
1450 parse_n_real(weights, &nweights, &(expand->init_lambda_weights), wi);
1453 snew(expand->init_lambda_weights, fep->n_lambda); /* initialize to zero */
1455 else if (nweights != fep->n_lambda)
1457 gmx_fatal(FARGS, "Number of weights (%d) is not equal to number of lambda values (%d)",
1458 nweights, fep->n_lambda);
1460 if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
1462 expand->nstexpanded = fep->nstdhdl;
1463 /* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
1468 static void do_simtemp_params(t_inputrec *ir)
1471 snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda);
1472 GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]);
1476 convertYesNos(warninp_t /*wi*/, gmx::ArrayRef<const std::string> inputs, const char * /*name*/, gmx_bool *outputs)
1479 for (const auto &input : inputs)
1481 outputs[i] = gmx::equalCaseInsensitive(input, "Y", 1);
1486 template <typename T> void
1487 convertInts(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, T *outputs)
1490 for (const auto &input : inputs)
1494 outputs[i] = gmx::fromStdString<T>(input);
1496 catch (gmx::GromacsException &)
1498 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of integers separated by spaces.",
1500 warning_error(wi, message);
1507 convertReals(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, real *outputs)
1510 for (const auto &input : inputs)
1514 outputs[i] = gmx::fromString<real>(input);
1516 catch (gmx::GromacsException &)
1518 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1520 warning_error(wi, message);
1527 convertRvecs(warninp_t wi, gmx::ArrayRef<const std::string> inputs, const char *name, rvec *outputs)
1530 for (const auto &input : inputs)
1534 outputs[i][d] = gmx::fromString<real>(input);
1536 catch (gmx::GromacsException &)
1538 auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.",
1540 warning_error(wi, message);
1551 static void do_wall_params(t_inputrec *ir,
1552 char *wall_atomtype, char *wall_density,
1556 opts->wall_atomtype[0] = nullptr;
1557 opts->wall_atomtype[1] = nullptr;
1559 ir->wall_atomtype[0] = -1;
1560 ir->wall_atomtype[1] = -1;
1561 ir->wall_density[0] = 0;
1562 ir->wall_density[1] = 0;
1566 auto wallAtomTypes = gmx::splitString(wall_atomtype);
1567 if (wallAtomTypes.size() != size_t(ir->nwall))
1569 gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu",
1570 ir->nwall, wallAtomTypes.size());
1572 for (int i = 0; i < ir->nwall; i++)
1574 opts->wall_atomtype[i] = gmx_strdup(wallAtomTypes[i].c_str());
1577 if (ir->wall_type == ewt93 || ir->wall_type == ewt104)
1579 auto wallDensity = gmx::splitString(wall_density);
1580 if (wallDensity.size() != size_t(ir->nwall))
1582 gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall, wallDensity.size());
1584 convertReals(wi, wallDensity, "wall-density", ir->wall_density);
1585 for (int i = 0; i < ir->nwall; i++)
1587 if (ir->wall_density[i] <= 0)
1589 gmx_fatal(FARGS, "wall-density[%d] = %f\n", i, ir->wall_density[i]);
1596 static void add_wall_energrps(SimulationGroups *groups, int nwall, t_symtab *symtab)
1600 AtomGroupIndices *grps = &(groups->groups[SimulationAtomGroupType::EnergyOutput]);
1601 for (int i = 0; i < nwall; i++)
1603 groups->groupNames.emplace_back(
1606 gmx::formatString("wall%d", i).c_str()));
1607 grps->emplace_back(groups->groupNames.size() - 1);
1612 static void read_expandedparams(std::vector<t_inpfile> *inp,
1613 t_expanded *expand, warninp_t wi)
1615 /* read expanded ensemble parameters */
1616 printStringNewline(inp, "expanded ensemble variables");
1617 expand->nstexpanded = get_eint(inp, "nstexpanded", -1, wi);
1618 expand->elamstats = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
1619 expand->elmcmove = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
1620 expand->elmceq = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
1621 expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
1622 expand->equil_samples = get_eint(inp, "weight-equil-number-samples", -1, wi);
1623 expand->equil_steps = get_eint(inp, "weight-equil-number-steps", -1, wi);
1624 expand->equil_wl_delta = get_ereal(inp, "weight-equil-wl-delta", -1, wi);
1625 expand->equil_ratio = get_ereal(inp, "weight-equil-count-ratio", -1, wi);
1626 printStringNewline(inp, "Seed for Monte Carlo in lambda space");
1627 expand->lmc_seed = get_eint(inp, "lmc-seed", -1, wi);
1628 expand->mc_temp = get_ereal(inp, "mc-temperature", -1, wi);
1629 expand->lmc_repeats = get_eint(inp, "lmc-repeats", 1, wi);
1630 expand->gibbsdeltalam = get_eint(inp, "lmc-gibbsdelta", -1, wi);
1631 expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi);
1632 expand->bSymmetrizedTMatrix = (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0);
1633 expand->nstTij = get_eint(inp, "nst-transition-matrix", -1, wi);
1634 expand->minvarmin = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
1635 expand->c_range = get_eint(inp, "weight-c-range", 0, wi); /* default is just C=0 */
1636 expand->wl_scale = get_ereal(inp, "wl-scale", 0.8, wi);
1637 expand->wl_ratio = get_ereal(inp, "wl-ratio", 0.8, wi);
1638 expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi);
1639 expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
1642 /*! \brief Return whether an end state with the given coupling-lambda
1643 * value describes fully-interacting VDW.
1645 * \param[in] couple_lambda_value Enumeration ecouplam value describing the end state
1646 * \return Whether VDW is on (i.e. the user chose vdw or vdw-q in the .mdp file)
1648 static bool couple_lambda_has_vdw_on(int couple_lambda_value)
1650 return (couple_lambda_value == ecouplamVDW ||
1651 couple_lambda_value == ecouplamVDWQ);
1657 class MdpErrorHandler : public gmx::IKeyValueTreeErrorHandler
1660 explicit MdpErrorHandler(warninp_t wi)
1661 : wi_(wi), mapping_(nullptr)
1665 void setBackMapping(const gmx::IKeyValueTreeBackMapping &mapping)
1667 mapping_ = &mapping;
1670 bool onError(gmx::UserInputError *ex, const gmx::KeyValueTreePath &context) override
1672 ex->prependContext(gmx::formatString("Error in mdp option \"%s\":",
1673 getOptionName(context).c_str()));
1674 std::string message = gmx::formatExceptionMessageToString(*ex);
1675 warning_error(wi_, message.c_str());
1680 std::string getOptionName(const gmx::KeyValueTreePath &context)
1682 if (mapping_ != nullptr)
1684 gmx::KeyValueTreePath path = mapping_->originalPath(context);
1685 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
1688 GMX_ASSERT(context.size() == 1, "Inconsistent context for mdp option parsing");
1693 const gmx::IKeyValueTreeBackMapping *mapping_;
1698 void get_ir(const char *mdparin, const char *mdparout,
1699 gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
1700 WriteMdpHeader writeMdpHeader, warninp_t wi)
1703 double dumdub[2][6];
1705 char warn_buf[STRLEN];
1706 t_lambda *fep = ir->fepvals;
1707 t_expanded *expand = ir->expandedvals;
1709 const char *no_names[] = { "no", nullptr };
1711 init_inputrec_strings();
1712 gmx::TextInputFile stream(mdparin);
1713 std::vector<t_inpfile> inp = read_inpfile(&stream, mdparin, wi);
1715 snew(dumstr[0], STRLEN);
1716 snew(dumstr[1], STRLEN);
1718 if (-1 == search_einp(inp, "cutoff-scheme"))
1721 "%s did not specify a value for the .mdp option "
1722 "\"cutoff-scheme\". As of GROMACS 2020, the Verlet scheme "
1723 "is the only cutoff scheme supported. This may affect your "
1724 "simulation if you are using an old mdp file that assumes use "
1725 "of the (removed) group cutoff scheme.", mdparin);
1726 warning_note(wi, warn_buf);
1729 /* ignore the following deprecated commands */
1730 replace_inp_entry(inp, "title", nullptr);
1731 replace_inp_entry(inp, "cpp", nullptr);
1732 replace_inp_entry(inp, "domain-decomposition", nullptr);
1733 replace_inp_entry(inp, "andersen-seed", nullptr);
1734 replace_inp_entry(inp, "dihre", nullptr);
1735 replace_inp_entry(inp, "dihre-fc", nullptr);
1736 replace_inp_entry(inp, "dihre-tau", nullptr);
1737 replace_inp_entry(inp, "nstdihreout", nullptr);
1738 replace_inp_entry(inp, "nstcheckpoint", nullptr);
1739 replace_inp_entry(inp, "optimize-fft", nullptr);
1740 replace_inp_entry(inp, "adress_type", nullptr);
1741 replace_inp_entry(inp, "adress_const_wf", nullptr);
1742 replace_inp_entry(inp, "adress_ex_width", nullptr);
1743 replace_inp_entry(inp, "adress_hy_width", nullptr);
1744 replace_inp_entry(inp, "adress_ex_forcecap", nullptr);
1745 replace_inp_entry(inp, "adress_interface_correction", nullptr);
1746 replace_inp_entry(inp, "adress_site", nullptr);
1747 replace_inp_entry(inp, "adress_reference_coords", nullptr);
1748 replace_inp_entry(inp, "adress_tf_grp_names", nullptr);
1749 replace_inp_entry(inp, "adress_cg_grp_names", nullptr);
1750 replace_inp_entry(inp, "adress_do_hybridpairs", nullptr);
1751 replace_inp_entry(inp, "rlistlong", nullptr);
1752 replace_inp_entry(inp, "nstcalclr", nullptr);
1753 replace_inp_entry(inp, "pull-print-com2", nullptr);
1754 replace_inp_entry(inp, "gb-algorithm", nullptr);
1755 replace_inp_entry(inp, "nstgbradii", nullptr);
1756 replace_inp_entry(inp, "rgbradii", nullptr);
1757 replace_inp_entry(inp, "gb-epsilon-solvent", nullptr);
1758 replace_inp_entry(inp, "gb-saltconc", nullptr);
1759 replace_inp_entry(inp, "gb-obc-alpha", nullptr);
1760 replace_inp_entry(inp, "gb-obc-beta", nullptr);
1761 replace_inp_entry(inp, "gb-obc-gamma", nullptr);
1762 replace_inp_entry(inp, "gb-dielectric-offset", nullptr);
1763 replace_inp_entry(inp, "sa-algorithm", nullptr);
1764 replace_inp_entry(inp, "sa-surface-tension", nullptr);
1765 replace_inp_entry(inp, "ns-type", nullptr);
1767 /* replace the following commands with the clearer new versions*/
1768 replace_inp_entry(inp, "unconstrained-start", "continuation");
1769 replace_inp_entry(inp, "foreign-lambda", "fep-lambdas");
1770 replace_inp_entry(inp, "verlet-buffer-drift", "verlet-buffer-tolerance");
1771 replace_inp_entry(inp, "nstxtcout", "nstxout-compressed");
1772 replace_inp_entry(inp, "xtc-grps", "compressed-x-grps");
1773 replace_inp_entry(inp, "xtc-precision", "compressed-x-precision");
1774 replace_inp_entry(inp, "pull-print-com1", "pull-print-com");
1776 printStringNewline(&inp, "VARIOUS PREPROCESSING OPTIONS");
1777 printStringNoNewline(&inp, "Preprocessor information: use cpp syntax.");
1778 printStringNoNewline(&inp, "e.g.: -I/home/joe/doe -I/home/mary/roe");
1779 setStringEntry(&inp, "include", opts->include, nullptr);
1780 printStringNoNewline(&inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)");
1781 setStringEntry(&inp, "define", opts->define, nullptr);
1783 printStringNewline(&inp, "RUN CONTROL PARAMETERS");
1784 ir->eI = get_eeenum(&inp, "integrator", ei_names, wi);
1785 printStringNoNewline(&inp, "Start time and timestep in ps");
1786 ir->init_t = get_ereal(&inp, "tinit", 0.0, wi);
1787 ir->delta_t = get_ereal(&inp, "dt", 0.001, wi);
1788 ir->nsteps = get_eint64(&inp, "nsteps", 0, wi);
1789 printStringNoNewline(&inp, "For exact run continuation or redoing part of a run");
1790 ir->init_step = get_eint64(&inp, "init-step", 0, wi);
1791 printStringNoNewline(&inp, "Part index is updated automatically on checkpointing (keeps files separate)");
1792 ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
1793 printStringNoNewline(&inp, "mode for center of mass motion removal");
1794 ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi);
1795 printStringNoNewline(&inp, "number of steps for center of mass motion removal");
1796 ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi);
1797 printStringNoNewline(&inp, "group(s) for center of mass motion removal");
1798 setStringEntry(&inp, "comm-grps", is->vcm, nullptr);
1800 printStringNewline(&inp, "LANGEVIN DYNAMICS OPTIONS");
1801 printStringNoNewline(&inp, "Friction coefficient (amu/ps) and random seed");
1802 ir->bd_fric = get_ereal(&inp, "bd-fric", 0.0, wi);
1803 ir->ld_seed = get_eint64(&inp, "ld-seed", -1, wi);
1806 printStringNewline(&inp, "ENERGY MINIMIZATION OPTIONS");
1807 printStringNoNewline(&inp, "Force tolerance and initial step-size");
1808 ir->em_tol = get_ereal(&inp, "emtol", 10.0, wi);
1809 ir->em_stepsize = get_ereal(&inp, "emstep", 0.01, wi);
1810 printStringNoNewline(&inp, "Max number of iterations in relax-shells");
1811 ir->niter = get_eint(&inp, "niter", 20, wi);
1812 printStringNoNewline(&inp, "Step size (ps^2) for minimization of flexible constraints");
1813 ir->fc_stepsize = get_ereal(&inp, "fcstep", 0, wi);
1814 printStringNoNewline(&inp, "Frequency of steepest descents steps when doing CG");
1815 ir->nstcgsteep = get_eint(&inp, "nstcgsteep", 1000, wi);
1816 ir->nbfgscorr = get_eint(&inp, "nbfgscorr", 10, wi);
1818 printStringNewline(&inp, "TEST PARTICLE INSERTION OPTIONS");
1819 ir->rtpi = get_ereal(&inp, "rtpi", 0.05, wi);
1821 /* Output options */
1822 printStringNewline(&inp, "OUTPUT CONTROL OPTIONS");
1823 printStringNoNewline(&inp, "Output frequency for coords (x), velocities (v) and forces (f)");
1824 ir->nstxout = get_eint(&inp, "nstxout", 0, wi);
1825 ir->nstvout = get_eint(&inp, "nstvout", 0, wi);
1826 ir->nstfout = get_eint(&inp, "nstfout", 0, wi);
1827 printStringNoNewline(&inp, "Output frequency for energies to log file and energy file");
1828 ir->nstlog = get_eint(&inp, "nstlog", 1000, wi);
1829 ir->nstcalcenergy = get_eint(&inp, "nstcalcenergy", 100, wi);
1830 ir->nstenergy = get_eint(&inp, "nstenergy", 1000, wi);
1831 printStringNoNewline(&inp, "Output frequency and precision for .xtc file");
1832 ir->nstxout_compressed = get_eint(&inp, "nstxout-compressed", 0, wi);
1833 ir->x_compression_precision = get_ereal(&inp, "compressed-x-precision", 1000.0, wi);
1834 printStringNoNewline(&inp, "This selects the subset of atoms for the compressed");
1835 printStringNoNewline(&inp, "trajectory file. You can select multiple groups. By");
1836 printStringNoNewline(&inp, "default, all atoms will be written.");
1837 setStringEntry(&inp, "compressed-x-grps", is->x_compressed_groups, nullptr);
1838 printStringNoNewline(&inp, "Selection of energy groups");
1839 setStringEntry(&inp, "energygrps", is->energy, nullptr);
1841 /* Neighbor searching */
1842 printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
1843 printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)");
1844 ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi);
1845 printStringNoNewline(&inp, "nblist update frequency");
1846 ir->nstlist = get_eint(&inp, "nstlist", 10, wi);
1847 printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
1848 ir->ePBC = get_eeenum(&inp, "pbc", epbc_names, wi);
1849 ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0;
1850 printStringNoNewline(&inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
1851 printStringNoNewline(&inp, "a value of -1 means: use rlist");
1852 ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance", 0.005, wi);
1853 printStringNoNewline(&inp, "nblist cut-off");
1854 ir->rlist = get_ereal(&inp, "rlist", 1.0, wi);
1855 printStringNoNewline(&inp, "long-range cut-off for switched potentials");
1857 /* Electrostatics */
1858 printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
1859 printStringNoNewline(&inp, "Method for doing electrostatics");
1860 ir->coulombtype = get_eeenum(&inp, "coulombtype", eel_names, wi);
1861 ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi);
1862 printStringNoNewline(&inp, "cut-off lengths");
1863 ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi);
1864 ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi);
1865 printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
1866 ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi);
1867 ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
1868 printStringNoNewline(&inp, "Method for doing Van der Waals");
1869 ir->vdwtype = get_eeenum(&inp, "vdw-type", evdw_names, wi);
1870 ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi);
1871 printStringNoNewline(&inp, "cut-off lengths");
1872 ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi);
1873 ir->rvdw = get_ereal(&inp, "rvdw", 1.0, wi);
1874 printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
1875 ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi);
1876 printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
1877 ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
1878 printStringNoNewline(&inp, "Separate tables between energy group pairs");
1879 setStringEntry(&inp, "energygrp-table", is->egptable, nullptr);
1880 printStringNoNewline(&inp, "Spacing for the PME/PPPM FFT grid");
1881 ir->fourier_spacing = get_ereal(&inp, "fourierspacing", 0.12, wi);
1882 printStringNoNewline(&inp, "FFT grid size, when a value is 0 fourierspacing will be used");
1883 ir->nkx = get_eint(&inp, "fourier-nx", 0, wi);
1884 ir->nky = get_eint(&inp, "fourier-ny", 0, wi);
1885 ir->nkz = get_eint(&inp, "fourier-nz", 0, wi);
1886 printStringNoNewline(&inp, "EWALD/PME/PPPM parameters");
1887 ir->pme_order = get_eint(&inp, "pme-order", 4, wi);
1888 ir->ewald_rtol = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
1889 ir->ewald_rtol_lj = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
1890 ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
1891 ir->ewald_geometry = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
1892 ir->epsilon_surface = get_ereal(&inp, "epsilon-surface", 0.0, wi);
1894 /* Implicit solvation is no longer supported, but we need grompp
1895 to be able to refuse old .mdp files that would have built a tpr
1896 to run it. Thus, only "no" is accepted. */
1897 ir->implicit_solvent = (get_eeenum(&inp, "implicit-solvent", no_names, wi) != 0);
1899 /* Coupling stuff */
1900 printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
1901 printStringNoNewline(&inp, "Temperature coupling");
1902 ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
1903 ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi);
1904 ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
1905 ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
1906 printStringNoNewline(&inp, "Groups to couple separately");
1907 setStringEntry(&inp, "tc-grps", is->tcgrps, nullptr);
1908 printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
1909 setStringEntry(&inp, "tau-t", is->tau_t, nullptr);
1910 setStringEntry(&inp, "ref-t", is->ref_t, nullptr);
1911 printStringNoNewline(&inp, "pressure coupling");
1912 ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
1913 ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
1914 ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
1915 printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
1916 ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi);
1917 setStringEntry(&inp, "compressibility", dumstr[0], nullptr);
1918 setStringEntry(&inp, "ref-p", dumstr[1], nullptr);
1919 printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
1920 ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
1923 printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
1924 ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0);
1925 printStringNoNewline(&inp, "Groups treated Quantum Mechanically");
1926 setStringEntry(&inp, "QMMM-grps", is->QMMM, nullptr);
1927 printStringNoNewline(&inp, "QM method");
1928 setStringEntry(&inp, "QMmethod", is->QMmethod, nullptr);
1929 printStringNoNewline(&inp, "QMMM scheme");
1930 ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme", eQMMMscheme_names, wi);
1931 printStringNoNewline(&inp, "QM basisset");
1932 setStringEntry(&inp, "QMbasis", is->QMbasis, nullptr);
1933 printStringNoNewline(&inp, "QM charge");
1934 setStringEntry(&inp, "QMcharge", is->QMcharge, nullptr);
1935 printStringNoNewline(&inp, "QM multiplicity");
1936 setStringEntry(&inp, "QMmult", is->QMmult, nullptr);
1937 printStringNoNewline(&inp, "Surface Hopping");
1938 setStringEntry(&inp, "SH", is->bSH, nullptr);
1939 printStringNoNewline(&inp, "CAS space options");
1940 setStringEntry(&inp, "CASorbitals", is->CASorbitals, nullptr);
1941 setStringEntry(&inp, "CASelectrons", is->CASelectrons, nullptr);
1942 setStringEntry(&inp, "SAon", is->SAon, nullptr);
1943 setStringEntry(&inp, "SAoff", is->SAoff, nullptr);
1944 setStringEntry(&inp, "SAsteps", is->SAsteps, nullptr);
1945 printStringNoNewline(&inp, "Scale factor for MM charges");
1946 ir->scalefactor = get_ereal(&inp, "MMChargeScaleFactor", 1.0, wi);
1948 /* Simulated annealing */
1949 printStringNewline(&inp, "SIMULATED ANNEALING");
1950 printStringNoNewline(&inp, "Type of annealing for each temperature group (no/single/periodic)");
1951 setStringEntry(&inp, "annealing", is->anneal, nullptr);
1952 printStringNoNewline(&inp, "Number of time points to use for specifying annealing in each group");
1953 setStringEntry(&inp, "annealing-npoints", is->anneal_npoints, nullptr);
1954 printStringNoNewline(&inp, "List of times at the annealing points for each group");
1955 setStringEntry(&inp, "annealing-time", is->anneal_time, nullptr);
1956 printStringNoNewline(&inp, "Temp. at each annealing point, for each group.");
1957 setStringEntry(&inp, "annealing-temp", is->anneal_temp, nullptr);
1960 printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
1961 opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0);
1962 opts->tempi = get_ereal(&inp, "gen-temp", 300.0, wi);
1963 opts->seed = get_eint(&inp, "gen-seed", -1, wi);
1966 printStringNewline(&inp, "OPTIONS FOR BONDS");
1967 opts->nshake = get_eeenum(&inp, "constraints", constraints, wi);
1968 printStringNoNewline(&inp, "Type of constraint algorithm");
1969 ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
1970 printStringNoNewline(&inp, "Do not constrain the start configuration");
1971 ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0);
1972 printStringNoNewline(&inp, "Use successive overrelaxation to reduce the number of shake iterations");
1973 ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0);
1974 printStringNoNewline(&inp, "Relative tolerance of shake");
1975 ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
1976 printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
1977 ir->nProjOrder = get_eint(&inp, "lincs-order", 4, wi);
1978 printStringNoNewline(&inp, "Number of iterations in the final step of LINCS. 1 is fine for");
1979 printStringNoNewline(&inp, "normal simulations, but use 2 to conserve energy in NVE runs.");
1980 printStringNoNewline(&inp, "For energy minimization with constraints it should be 4 to 8.");
1981 ir->nLincsIter = get_eint(&inp, "lincs-iter", 1, wi);
1982 printStringNoNewline(&inp, "Lincs will write a warning to the stderr if in one step a bond");
1983 printStringNoNewline(&inp, "rotates over more degrees than");
1984 ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
1985 printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
1986 opts->bMorse = (get_eeenum(&inp, "morse", yesno_names, wi) != 0);
1988 /* Energy group exclusions */
1989 printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
1990 printStringNoNewline(&inp, "Pairs of energy groups for which all non-bonded interactions are excluded");
1991 setStringEntry(&inp, "energygrp-excl", is->egpexcl, nullptr);
1994 printStringNewline(&inp, "WALLS");
1995 printStringNoNewline(&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
1996 ir->nwall = get_eint(&inp, "nwall", 0, wi);
1997 ir->wall_type = get_eeenum(&inp, "wall-type", ewt_names, wi);
1998 ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
1999 setStringEntry(&inp, "wall-atomtype", is->wall_atomtype, nullptr);
2000 setStringEntry(&inp, "wall-density", is->wall_density, nullptr);
2001 ir->wall_ewald_zfac = get_ereal(&inp, "wall-ewald-zfac", 3, wi);
2004 printStringNewline(&inp, "COM PULLING");
2005 ir->bPull = (get_eeenum(&inp, "pull", yesno_names, wi) != 0);
2009 is->pull_grp = read_pullparams(&inp, ir->pull, wi);
2013 NOTE: needs COM pulling input */
2014 printStringNewline(&inp, "AWH biasing");
2015 ir->bDoAwh = (get_eeenum(&inp, "awh", yesno_names, wi) != 0);
2020 ir->awhParams = gmx::readAndCheckAwhParams(&inp, ir, wi);
2024 gmx_fatal(FARGS, "AWH biasing is only compatible with COM pulling turned on");
2028 /* Enforced rotation */
2029 printStringNewline(&inp, "ENFORCED ROTATION");
2030 printStringNoNewline(&inp, "Enforced rotation: No or Yes");
2031 ir->bRot = (get_eeenum(&inp, "rotation", yesno_names, wi) != 0);
2035 is->rot_grp = read_rotparams(&inp, ir->rot, wi);
2038 /* Interactive MD */
2040 printStringNewline(&inp, "Group to display and/or manipulate in interactive MD session");
2041 setStringEntry(&inp, "IMD-group", is->imd_grp, nullptr);
2042 if (is->imd_grp[0] != '\0')
2049 printStringNewline(&inp, "NMR refinement stuff");
2050 printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
2051 ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi);
2052 printStringNoNewline(&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
2053 ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
2054 printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
2055 ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0);
2056 ir->dr_fc = get_ereal(&inp, "disre-fc", 1000.0, wi);
2057 ir->dr_tau = get_ereal(&inp, "disre-tau", 0.0, wi);
2058 printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
2059 ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
2060 printStringNoNewline(&inp, "Orientation restraints: No or Yes");
2061 opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0);
2062 printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
2063 ir->orires_fc = get_ereal(&inp, "orire-fc", 0.0, wi);
2064 ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
2065 setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp, nullptr);
2066 printStringNoNewline(&inp, "Output frequency for trace(SD) and S to energy file");
2067 ir->nstorireout = get_eint(&inp, "nstorireout", 100, wi);
2069 /* free energy variables */
2070 printStringNewline(&inp, "Free energy variables");
2071 ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
2072 setStringEntry(&inp, "couple-moltype", is->couple_moltype, nullptr);
2073 opts->couple_lam0 = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
2074 opts->couple_lam1 = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
2075 opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0);
2077 fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
2079 it was not entered */
2080 fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
2081 fep->delta_lambda = get_ereal(&inp, "delta-lambda", 0.0, wi);
2082 fep->nstdhdl = get_eint(&inp, "nstdhdl", 50, wi);
2083 setStringEntry(&inp, "fep-lambdas", is->fep_lambda[efptFEP], nullptr);
2084 setStringEntry(&inp, "mass-lambdas", is->fep_lambda[efptMASS], nullptr);
2085 setStringEntry(&inp, "coul-lambdas", is->fep_lambda[efptCOUL], nullptr);
2086 setStringEntry(&inp, "vdw-lambdas", is->fep_lambda[efptVDW], nullptr);
2087 setStringEntry(&inp, "bonded-lambdas", is->fep_lambda[efptBONDED], nullptr);
2088 setStringEntry(&inp, "restraint-lambdas", is->fep_lambda[efptRESTRAINT], nullptr);
2089 setStringEntry(&inp, "temperature-lambdas", is->fep_lambda[efptTEMPERATURE], nullptr);
2090 fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
2091 setStringEntry(&inp, "init-lambda-weights", is->lambda_weights, nullptr);
2092 fep->edHdLPrintEnergy = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
2093 fep->sc_alpha = get_ereal(&inp, "sc-alpha", 0.0, wi);
2094 fep->sc_power = get_eint(&inp, "sc-power", 1, wi);
2095 fep->sc_r_power = get_ereal(&inp, "sc-r-power", 6.0, wi);
2096 fep->sc_sigma = get_ereal(&inp, "sc-sigma", 0.3, wi);
2097 fep->bScCoul = (get_eeenum(&inp, "sc-coul", yesno_names, wi) != 0);
2098 fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
2099 fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2100 fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
2101 fep->dhdl_derivatives = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
2102 fep->dh_hist_size = get_eint(&inp, "dh_hist_size", 0, wi);
2103 fep->dh_hist_spacing = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
2105 /* Non-equilibrium MD stuff */
2106 printStringNewline(&inp, "Non-equilibrium MD stuff");
2107 setStringEntry(&inp, "acc-grps", is->accgrps, nullptr);
2108 setStringEntry(&inp, "accelerate", is->acc, nullptr);
2109 setStringEntry(&inp, "freezegrps", is->freeze, nullptr);
2110 setStringEntry(&inp, "freezedim", is->frdim, nullptr);
2111 ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
2112 setStringEntry(&inp, "deform", is->deform, nullptr);
2114 /* simulated tempering variables */
2115 printStringNewline(&inp, "simulated tempering variables");
2116 ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0);
2117 ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
2118 ir->simtempvals->simtemp_low = get_ereal(&inp, "sim-temp-low", 300.0, wi);
2119 ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi);
2121 /* expanded ensemble variables */
2122 if (ir->efep == efepEXPANDED || ir->bSimTemp)
2124 read_expandedparams(&inp, expand, wi);
2127 /* Electric fields */
2129 gmx::KeyValueTreeObject convertedValues = flatKeyValueTreeFromInpFile(inp);
2130 gmx::KeyValueTreeTransformer transform;
2131 transform.rules()->addRule()
2132 .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
2133 mdModules->initMdpTransform(transform.rules());
2134 for (const auto &path : transform.mappedPaths())
2136 GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
2137 mark_einp_set(inp, path[0].c_str());
2139 MdpErrorHandler errorHandler(wi);
2141 = transform.transform(convertedValues, &errorHandler);
2142 ir->params = new gmx::KeyValueTreeObject(result.object());
2143 mdModules->adjustInputrecBasedOnModules(ir);
2144 errorHandler.setBackMapping(result.backMapping());
2145 mdModules->assignOptionsToModules(*ir->params, &errorHandler);
2148 /* Ion/water position swapping ("computational electrophysiology") */
2149 printStringNewline(&inp, "Ion/water position swapping for computational electrophysiology setups");
2150 printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
2151 ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
2152 if (ir->eSwapCoords != eswapNO)
2159 printStringNoNewline(&inp, "Swap attempt frequency");
2160 ir->swap->nstswap = get_eint(&inp, "swap-frequency", 1, wi);
2161 printStringNoNewline(&inp, "Number of ion types to be controlled");
2162 nIonTypes = get_eint(&inp, "iontypes", 1, wi);
2165 warning_error(wi, "You need to provide at least one ion type for position exchanges.");
2167 ir->swap->ngrp = nIonTypes + eSwapFixedGrpNR;
2168 snew(ir->swap->grp, ir->swap->ngrp);
2169 for (i = 0; i < ir->swap->ngrp; i++)
2171 snew(ir->swap->grp[i].molname, STRLEN);
2173 printStringNoNewline(&inp, "Two index groups that contain the compartment-partitioning atoms");
2174 setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
2175 setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
2176 printStringNoNewline(&inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used");
2177 ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0);
2178 ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0);
2180 printStringNoNewline(&inp, "Name of solvent molecules");
2181 setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
2183 printStringNoNewline(&inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)");
2184 printStringNoNewline(&inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,");
2185 printStringNoNewline(&inp, "however, if correctly defined, the permeation events are recorded per channel");
2186 ir->swap->cyl0r = get_ereal(&inp, "cyl0-r", 2.0, wi);
2187 ir->swap->cyl0u = get_ereal(&inp, "cyl0-up", 1.0, wi);
2188 ir->swap->cyl0l = get_ereal(&inp, "cyl0-down", 1.0, wi);
2189 ir->swap->cyl1r = get_ereal(&inp, "cyl1-r", 2.0, wi);
2190 ir->swap->cyl1u = get_ereal(&inp, "cyl1-up", 1.0, wi);
2191 ir->swap->cyl1l = get_ereal(&inp, "cyl1-down", 1.0, wi);
2193 printStringNoNewline(&inp, "Average the number of ions per compartment over these many swap attempt steps");
2194 ir->swap->nAverage = get_eint(&inp, "coupl-steps", 10, wi);
2196 printStringNoNewline(&inp, "Names of the ion types that can be exchanged with solvent molecules,");
2197 printStringNoNewline(&inp, "and the requested number of ions of this type in compartments A and B");
2198 printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
2199 for (i = 0; i < nIonTypes; i++)
2201 int ig = eSwapFixedGrpNR + i;
2203 sprintf(buf, "iontype%d-name", i);
2204 setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
2205 sprintf(buf, "iontype%d-in-A", i);
2206 ir->swap->grp[ig].nmolReq[0] = get_eint(&inp, buf, -1, wi);
2207 sprintf(buf, "iontype%d-in-B", i);
2208 ir->swap->grp[ig].nmolReq[1] = get_eint(&inp, buf, -1, wi);
2211 printStringNoNewline(&inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
2212 printStringNoNewline(&inp, "at maximum distance (= bulk concentration) to the split group layers. However,");
2213 printStringNoNewline(&inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
2214 printStringNoNewline(&inp, "towards one of the compartment-partitioning layers (at +/- 1.0).");
2215 ir->swap->bulkOffset[0] = get_ereal(&inp, "bulk-offsetA", 0.0, wi);
2216 ir->swap->bulkOffset[1] = get_ereal(&inp, "bulk-offsetB", 0.0, wi);
2217 if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0)
2218 || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) )
2220 warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !");
2223 printStringNoNewline(&inp, "Start to swap ions if threshold difference to requested count is reached");
2224 ir->swap->threshold = get_ereal(&inp, "threshold", 1.0, wi);
2227 /* AdResS is no longer supported, but we need grompp to be able to
2228 refuse to process old .mdp files that used it. */
2229 ir->bAdress = (get_eeenum(&inp, "adress", no_names, wi) != 0);
2231 /* User defined thingies */
2232 printStringNewline(&inp, "User defined thingies");
2233 setStringEntry(&inp, "user1-grps", is->user1, nullptr);
2234 setStringEntry(&inp, "user2-grps", is->user2, nullptr);
2235 ir->userint1 = get_eint(&inp, "userint1", 0, wi);
2236 ir->userint2 = get_eint(&inp, "userint2", 0, wi);
2237 ir->userint3 = get_eint(&inp, "userint3", 0, wi);
2238 ir->userint4 = get_eint(&inp, "userint4", 0, wi);
2239 ir->userreal1 = get_ereal(&inp, "userreal1", 0, wi);
2240 ir->userreal2 = get_ereal(&inp, "userreal2", 0, wi);
2241 ir->userreal3 = get_ereal(&inp, "userreal3", 0, wi);
2242 ir->userreal4 = get_ereal(&inp, "userreal4", 0, wi);
2246 gmx::TextOutputFile stream(mdparout);
2247 write_inpfile(&stream, mdparout, &inp, FALSE, writeMdpHeader, wi);
2249 // Transform module data into a flat key-value tree for output.
2250 gmx::KeyValueTreeBuilder builder;
2251 gmx::KeyValueTreeObjectBuilder builderObject = builder.rootObject();
2252 mdModules->buildMdpOutput(&builderObject);
2254 gmx::TextWriter writer(&stream);
2255 writeKeyValueTreeAsMdp(&writer, builder.build());
2260 /* Process options if necessary */
2261 for (m = 0; m < 2; m++)
2263 for (i = 0; i < 2*DIM; i++)
2272 if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1)
2274 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 1)");
2276 dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX];
2278 case epctSEMIISOTROPIC:
2279 case epctSURFACETENSION:
2280 if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2)
2282 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 2)");
2284 dumdub[m][YY] = dumdub[m][XX];
2286 case epctANISOTROPIC:
2287 if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf",
2288 &(dumdub[m][XX]), &(dumdub[m][YY]), &(dumdub[m][ZZ]),
2289 &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5])) != 6)
2291 warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 6)");
2295 gmx_fatal(FARGS, "Pressure coupling type %s not implemented yet",
2296 epcoupltype_names[ir->epct]);
2300 clear_mat(ir->ref_p);
2301 clear_mat(ir->compress);
2302 for (i = 0; i < DIM; i++)
2304 ir->ref_p[i][i] = dumdub[1][i];
2305 ir->compress[i][i] = dumdub[0][i];
2307 if (ir->epct == epctANISOTROPIC)
2309 ir->ref_p[XX][YY] = dumdub[1][3];
2310 ir->ref_p[XX][ZZ] = dumdub[1][4];
2311 ir->ref_p[YY][ZZ] = dumdub[1][5];
2312 if (ir->ref_p[XX][YY] != 0 && ir->ref_p[XX][ZZ] != 0 && ir->ref_p[YY][ZZ] != 0)
2314 warning(wi, "All off-diagonal reference pressures are non-zero. Are you sure you want to apply a threefold shear stress?\n");
2316 ir->compress[XX][YY] = dumdub[0][3];
2317 ir->compress[XX][ZZ] = dumdub[0][4];
2318 ir->compress[YY][ZZ] = dumdub[0][5];
2319 for (i = 0; i < DIM; i++)
2321 for (m = 0; m < i; m++)
2323 ir->ref_p[i][m] = ir->ref_p[m][i];
2324 ir->compress[i][m] = ir->compress[m][i];
2329 if (ir->comm_mode == ecmNO)
2334 opts->couple_moltype = nullptr;
2335 if (strlen(is->couple_moltype) > 0)
2337 if (ir->efep != efepNO)
2339 opts->couple_moltype = gmx_strdup(is->couple_moltype);
2340 if (opts->couple_lam0 == opts->couple_lam1)
2342 warning(wi, "The lambda=0 and lambda=1 states for coupling are identical");
2344 if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE ||
2345 opts->couple_lam1 == ecouplamNONE))
2347 warning(wi, "For proper sampling of the (nearly) decoupled state, stochastic dynamics should be used");
2352 warning_note(wi, "Free energy is turned off, so we will not decouple the molecule listed in your input.");
2355 /* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */
2356 if (ir->efep != efepNO)
2358 if (fep->delta_lambda > 0)
2360 ir->efep = efepSLOWGROWTH;
2364 if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES)
2366 fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2367 warning_note(wi, "Old option for dhdl-print-energy given: "
2368 "changing \"yes\" to \"total\"\n");
2371 if (ir->bSimTemp && (fep->edHdLPrintEnergy == edHdLPrintEnergyNO))
2373 /* always print out the energy to dhdl if we are doing
2374 expanded ensemble, since we need the total energy for
2375 analysis if the temperature is changing. In some
2376 conditions one may only want the potential energy, so
2377 we will allow that if the appropriate mdp setting has
2378 been enabled. Otherwise, total it is:
2380 fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
2383 if ((ir->efep != efepNO) || ir->bSimTemp)
2385 ir->bExpanded = FALSE;
2386 if ((ir->efep == efepEXPANDED) || ir->bSimTemp)
2388 ir->bExpanded = TRUE;
2390 do_fep_params(ir, is->fep_lambda, is->lambda_weights, wi);
2391 if (ir->bSimTemp) /* done after fep params */
2393 do_simtemp_params(ir);
2396 /* Because sc-coul (=FALSE by default) only acts on the lambda state
2397 * setup and not on the old way of specifying the free-energy setup,
2398 * we should check for using soft-core when not needed, since that
2399 * can complicate the sampling significantly.
2400 * Note that we only check for the automated coupling setup.
2401 * If the (advanced) user does FEP through manual topology changes,
2402 * this check will not be triggered.
2404 if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 &&
2405 ir->fepvals->sc_alpha != 0 &&
2406 (couple_lambda_has_vdw_on(opts->couple_lam0) &&
2407 couple_lambda_has_vdw_on(opts->couple_lam1)))
2409 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.");
2414 ir->fepvals->n_lambda = 0;
2417 /* WALL PARAMETERS */
2419 do_wall_params(ir, is->wall_atomtype, is->wall_density, opts, wi);
2421 /* ORIENTATION RESTRAINT PARAMETERS */
2423 if (opts->bOrire && gmx::splitString(is->orirefitgrp).size() != 1)
2425 warning_error(wi, "ERROR: Need one orientation restraint fit group\n");
2428 /* DEFORMATION PARAMETERS */
2430 clear_mat(ir->deform);
2431 for (i = 0; i < 6; i++)
2436 double gmx_unused canary;
2437 int ndeform = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf %lf",
2438 &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]),
2439 &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]), &canary);
2441 if (strlen(is->deform) > 0 && ndeform != 6)
2443 warning_error(wi, gmx::formatString("Cannot parse exactly 6 box deformation velocities from string '%s'", is->deform).c_str());
2445 for (i = 0; i < 3; i++)
2447 ir->deform[i][i] = dumdub[0][i];
2449 ir->deform[YY][XX] = dumdub[0][3];
2450 ir->deform[ZZ][XX] = dumdub[0][4];
2451 ir->deform[ZZ][YY] = dumdub[0][5];
2452 if (ir->epc != epcNO)
2454 for (i = 0; i < 3; i++)
2456 for (j = 0; j <= i; j++)
2458 if (ir->deform[i][j] != 0 && ir->compress[i][j] != 0)
2460 warning_error(wi, "A box element has deform set and compressibility > 0");
2464 for (i = 0; i < 3; i++)
2466 for (j = 0; j < i; j++)
2468 if (ir->deform[i][j] != 0)
2470 for (m = j; m < DIM; m++)
2472 if (ir->compress[m][j] != 0)
2474 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.");
2475 warning(wi, warn_buf);
2483 /* Ion/water position swapping checks */
2484 if (ir->eSwapCoords != eswapNO)
2486 if (ir->swap->nstswap < 1)
2488 warning_error(wi, "swap_frequency must be 1 or larger when ion swapping is requested");
2490 if (ir->swap->nAverage < 1)
2492 warning_error(wi, "coupl_steps must be 1 or larger.\n");
2494 if (ir->swap->threshold < 1.0)
2496 warning_error(wi, "Ion count threshold must be at least 1.\n");
2504 static int search_QMstring(const char *s, int ng, const char *gn[])
2506 /* same as normal search_string, but this one searches QM strings */
2509 for (i = 0; (i < ng); i++)
2511 if (gmx_strcasecmp(s, gn[i]) == 0)
2517 gmx_fatal(FARGS, "this QM method or basisset (%s) is not implemented\n!", s);
2518 } /* search_QMstring */
2520 /* We would like gn to be const as well, but C doesn't allow this */
2521 /* TODO this is utility functionality (search for the index of a
2522 string in a collection), so should be refactored and located more
2524 int search_string(const char *s, int ng, char *gn[])
2528 for (i = 0; (i < ng); i++)
2530 if (gmx_strcasecmp(s, gn[i]) == 0)
2537 "Group %s referenced in the .mdp file was not found in the index file.\n"
2538 "Group names must match either [moleculetype] names or custom index group\n"
2539 "names, in which case you must supply an index file to the '-n' option\n"
2544 static bool do_numbering(int natoms, SimulationGroups *groups,
2545 gmx::ArrayRef<std::string> groupsFromMdpFile,
2546 t_blocka *block, char *gnames[],
2547 SimulationAtomGroupType gtype, int restnm,
2548 int grptp, bool bVerbose,
2551 unsigned short *cbuf;
2552 AtomGroupIndices *grps = &(groups->groups[gtype]);
2553 int j, gid, aj, ognr, ntot = 0;
2556 char warn_buf[STRLEN];
2558 title = shortName(gtype);
2561 /* Mark all id's as not set */
2562 for (int i = 0; (i < natoms); i++)
2567 for (int i = 0; i != groupsFromMdpFile.ssize(); ++i)
2569 /* Lookup the group name in the block structure */
2570 gid = search_string(groupsFromMdpFile[i].c_str(), block->nr, gnames);
2571 if ((grptp != egrptpONE) || (i == 0))
2573 grps->emplace_back(gid);
2576 /* Now go over the atoms in the group */
2577 for (j = block->index[gid]; (j < block->index[gid+1]); j++)
2582 /* Range checking */
2583 if ((aj < 0) || (aj >= natoms))
2585 gmx_fatal(FARGS, "Invalid atom number %d in indexfile", aj + 1);
2587 /* Lookup up the old group number */
2591 gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)",
2592 aj+1, title, ognr+1, i+1);
2596 /* Store the group number in buffer */
2597 if (grptp == egrptpONE)
2610 /* Now check whether we have done all atoms */
2614 if (grptp == egrptpALL)
2616 gmx_fatal(FARGS, "%d atoms are not part of any of the %s groups",
2617 natoms-ntot, title);
2619 else if (grptp == egrptpPART)
2621 sprintf(warn_buf, "%d atoms are not part of any of the %s groups",
2622 natoms-ntot, title);
2623 warning_note(wi, warn_buf);
2625 /* Assign all atoms currently unassigned to a rest group */
2626 for (j = 0; (j < natoms); j++)
2628 if (cbuf[j] == NOGID)
2630 cbuf[j] = grps->size();
2634 if (grptp != egrptpPART)
2639 "Making dummy/rest group for %s containing %d elements\n",
2640 title, natoms-ntot);
2642 /* Add group name "rest" */
2643 grps->emplace_back(restnm);
2645 /* Assign the rest name to all atoms not currently assigned to a group */
2646 for (j = 0; (j < natoms); j++)
2648 if (cbuf[j] == NOGID)
2650 // group size was not updated before this here, so need to use -1.
2651 cbuf[j] = grps->size() - 1;
2657 if (grps->size() == 1 && (ntot == 0 || ntot == natoms))
2659 /* All atoms are part of one (or no) group, no index required */
2660 groups->groupNumbers[gtype].clear();
2664 for (int j = 0; (j < natoms); j++)
2666 groups->groupNumbers[gtype].emplace_back(cbuf[j]);
2672 return (bRest && grptp == egrptpPART);
2675 static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
2678 pull_params_t *pull;
2679 int natoms, imin, jmin;
2680 int *nrdf2, *na_vcm, na_tot;
2681 double *nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub;
2686 * First calc 3xnr-atoms for each group
2687 * then subtract half a degree of freedom for each constraint
2689 * Only atoms and nuclei contribute to the degrees of freedom...
2694 const SimulationGroups &groups = mtop->groups;
2695 natoms = mtop->natoms;
2697 /* Allocate one more for a possible rest group */
2698 /* We need to sum degrees of freedom into doubles,
2699 * since floats give too low nrdf's above 3 million atoms.
2701 snew(nrdf_tc, groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()+1);
2702 snew(nrdf_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2703 snew(dof_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2704 snew(na_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2705 snew(nrdf_vcm_sub, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1);
2707 for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++)
2711 for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; i++)
2714 clear_ivec(dof_vcm[i]);
2716 nrdf_vcm_sub[i] = 0;
2718 snew(nrdf2, natoms);
2719 for (const AtomProxy atomP : AtomRange(*mtop))
2721 const t_atom &local = atomP.atom();
2722 int i = atomP.globalAtomNumber();
2724 if (local.ptype == eptAtom || local.ptype == eptNucleus)
2726 int g = getGroupType(groups, SimulationAtomGroupType::Freeze, i);
2727 for (int d = 0; d < DIM; d++)
2729 if (opts->nFreeze[g][d] == 0)
2731 /* Add one DOF for particle i (counted as 2*1) */
2733 /* VCM group i has dim d as a DOF */
2734 dof_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)][d] = 1;
2737 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, i)] += 0.5*nrdf2[i];
2738 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)] += 0.5*nrdf2[i];
2743 for (const gmx_molblock_t &molb : mtop->molblock)
2745 const gmx_moltype_t &molt = mtop->moltype[molb.type];
2746 const t_atom *atom = molt.atoms.atom;
2747 for (int mol = 0; mol < molb.nmol; mol++)
2749 for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
2751 gmx::ArrayRef<const int> ia = molt.ilist[ftype].iatoms;
2752 for (int i = 0; i < molt.ilist[ftype].size(); )
2754 /* Subtract degrees of freedom for the constraints,
2755 * if the particles still have degrees of freedom left.
2756 * If one of the particles is a vsite or a shell, then all
2757 * constraint motion will go there, but since they do not
2758 * contribute to the constraints the degrees of freedom do not
2761 int ai = as + ia[i + 1];
2762 int aj = as + ia[i + 2];
2763 if (((atom[ia[i + 1]].ptype == eptNucleus) ||
2764 (atom[ia[i + 1]].ptype == eptAtom)) &&
2765 ((atom[ia[i + 2]].ptype == eptNucleus) ||
2766 (atom[ia[i + 2]].ptype == eptAtom)))
2784 imin = std::min(imin, nrdf2[ai]);
2785 jmin = std::min(jmin, nrdf2[aj]);
2788 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin;
2789 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, aj)] -= 0.5*jmin;
2790 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
2791 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, aj)] -= 0.5*jmin;
2793 i += interaction_function[ftype].nratoms+1;
2796 gmx::ArrayRef<const int> ia = molt.ilist[F_SETTLE].iatoms;
2797 for (int i = 0; i < molt.ilist[F_SETTLE].size(); )
2799 /* Subtract 1 dof from every atom in the SETTLE */
2800 for (int j = 0; j < 3; j++)
2802 int ai = as + ia[i + 1 + j];
2803 imin = std::min(2, nrdf2[ai]);
2805 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin;
2806 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
2810 as += molt.atoms.nr;
2816 /* Correct nrdf for the COM constraints.
2817 * We correct using the TC and VCM group of the first atom
2818 * in the reference and pull group. If atoms in one pull group
2819 * belong to different TC or VCM groups it is anyhow difficult
2820 * to determine the optimal nrdf assignment.
2824 for (int i = 0; i < pull->ncoord; i++)
2826 if (pull->coord[i].eType != epullCONSTRAINT)
2833 for (int j = 0; j < 2; j++)
2835 const t_pull_group *pgrp;
2837 pgrp = &pull->group[pull->coord[i].group[j]];
2841 /* Subtract 1/2 dof from each group */
2842 int ai = pgrp->ind[0];
2843 nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin;
2844 nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
2845 if (nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] < 0)
2847 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)]]);
2852 /* We need to subtract the whole DOF from group j=1 */
2859 if (ir->nstcomm != 0)
2863 /* We remove COM motion up to dim ndof_com() */
2864 ndim_rm_vcm = ndof_com(ir);
2866 /* Subtract ndim_rm_vcm (or less with frozen dimensions) from
2867 * the number of degrees of freedom in each vcm group when COM
2868 * translation is removed and 6 when rotation is removed as well.
2870 for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++)
2872 switch (ir->comm_mode)
2875 case ecmLINEAR_ACCELERATION_CORRECTION:
2876 nrdf_vcm_sub[j] = 0;
2877 for (int d = 0; d < ndim_rm_vcm; d++)
2886 nrdf_vcm_sub[j] = 6;
2889 gmx_incons("Checking comm_mode");
2893 for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++)
2895 /* Count the number of atoms of TC group i for every VCM group */
2896 for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++)
2901 for (int ai = 0; ai < natoms; ai++)
2903 if (getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai) == i)
2905 na_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)]++;
2909 /* Correct for VCM removal according to the fraction of each VCM
2910 * group present in this TC group.
2912 nrdf_uc = nrdf_tc[i];
2914 for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++)
2916 if (nrdf_vcm[j] > nrdf_vcm_sub[j])
2918 nrdf_tc[i] += nrdf_uc*(static_cast<double>(na_vcm[j])/static_cast<double>(na_tot))*
2919 (nrdf_vcm[j] - nrdf_vcm_sub[j])/nrdf_vcm[j];
2924 for (int i = 0; (i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling])); i++)
2926 opts->nrdf[i] = nrdf_tc[i];
2927 if (opts->nrdf[i] < 0)
2932 "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
2933 gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]], opts->nrdf[i]);
2941 sfree(nrdf_vcm_sub);
2944 static bool do_egp_flag(t_inputrec *ir, SimulationGroups *groups,
2945 const char *option, const char *val, int flag)
2947 /* The maximum number of energy group pairs would be MAXPTR*(MAXPTR+1)/2.
2948 * But since this is much larger than STRLEN, such a line can not be parsed.
2949 * The real maximum is the number of names that fit in a string: STRLEN/2.
2951 #define EGP_MAX (STRLEN/2)
2955 auto names = gmx::splitString(val);
2956 if (names.size() % 2 != 0)
2958 gmx_fatal(FARGS, "The number of groups for %s is odd", option);
2960 nr = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
2962 for (size_t i = 0; i < names.size() / 2; i++)
2964 // TODO this needs to be replaced by a solution using std::find_if
2967 gmx_strcasecmp(names[2*i].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]])))
2973 gmx_fatal(FARGS, "%s in %s is not an energy group\n",
2974 names[2*i].c_str(), option);
2978 gmx_strcasecmp(names[2*i+1].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]])))
2984 gmx_fatal(FARGS, "%s in %s is not an energy group\n",
2985 names[2*i+1].c_str(), option);
2987 if ((j < nr) && (k < nr))
2989 ir->opts.egp_flags[nr*j+k] |= flag;
2990 ir->opts.egp_flags[nr*k+j] |= flag;
2999 static void make_swap_groups(
3004 int ig = -1, i = 0, gind;
3008 /* Just a quick check here, more thorough checks are in mdrun */
3009 if (strcmp(swap->grp[eGrpSplit0].molname, swap->grp[eGrpSplit1].molname) == 0)
3011 gmx_fatal(FARGS, "The split groups can not both be '%s'.", swap->grp[eGrpSplit0].molname);
3014 /* Get the index atoms of the split0, split1, solvent, and swap groups */
3015 for (ig = 0; ig < swap->ngrp; ig++)
3017 swapg = &swap->grp[ig];
3018 gind = search_string(swap->grp[ig].molname, grps->nr, gnames);
3019 swapg->nat = grps->index[gind+1] - grps->index[gind];
3023 fprintf(stderr, "%s group '%s' contains %d atoms.\n",
3024 ig < 3 ? eSwapFixedGrp_names[ig] : "Swap",
3025 swap->grp[ig].molname, swapg->nat);
3026 snew(swapg->ind, swapg->nat);
3027 for (i = 0; i < swapg->nat; i++)
3029 swapg->ind[i] = grps->a[grps->index[gind]+i];
3034 gmx_fatal(FARGS, "Swap group %s does not contain any atoms.", swap->grp[ig].molname);
3040 static void make_IMD_group(t_IMD *IMDgroup, char *IMDgname, t_blocka *grps, char **gnames)
3045 ig = search_string(IMDgname, grps->nr, gnames);
3046 IMDgroup->nat = grps->index[ig+1] - grps->index[ig];
3048 if (IMDgroup->nat > 0)
3050 fprintf(stderr, "Group '%s' with %d atoms can be activated for interactive molecular dynamics (IMD).\n",
3051 IMDgname, IMDgroup->nat);
3052 snew(IMDgroup->ind, IMDgroup->nat);
3053 for (i = 0; i < IMDgroup->nat; i++)
3055 IMDgroup->ind[i] = grps->a[grps->index[ig]+i];
3060 void do_index(const char* mdparin, const char *ndx,
3063 const gmx::MdModulesNotifier ¬ifier,
3067 t_blocka *defaultIndexGroups;
3071 char warnbuf[STRLEN], **gnames;
3075 int i, j, k, restnm;
3076 bool bExcl, bTable, bAnneal, bRest;
3077 char warn_buf[STRLEN];
3081 fprintf(stderr, "processing index file...\n");
3085 snew(defaultIndexGroups, 1);
3086 snew(defaultIndexGroups->index, 1);
3088 atoms_all = gmx_mtop_global_atoms(mtop);
3089 analyse(&atoms_all, defaultIndexGroups, &gnames, FALSE, TRUE);
3090 done_atom(&atoms_all);
3094 defaultIndexGroups = init_index(ndx, &gnames);
3097 SimulationGroups *groups = &mtop->groups;
3098 natoms = mtop->natoms;
3099 symtab = &mtop->symtab;
3101 for (int i = 0; (i < defaultIndexGroups->nr); i++)
3103 groups->groupNames.emplace_back(put_symtab(symtab, gnames[i]));
3105 groups->groupNames.emplace_back(put_symtab(symtab, "rest"));
3106 restnm = groups->groupNames.size() - 1;
3107 GMX_RELEASE_ASSERT(restnm == defaultIndexGroups->nr, "Size of allocations must match");
3108 srenew(gnames, defaultIndexGroups->nr+1);
3109 gnames[restnm] = *(groups->groupNames.back());
3111 set_warning_line(wi, mdparin, -1);
3113 auto temperatureCouplingTauValues = gmx::splitString(is->tau_t);
3114 auto temperatureCouplingReferenceValues = gmx::splitString(is->ref_t);
3115 auto temperatureCouplingGroupNames = gmx::splitString(is->tcgrps);
3116 if (temperatureCouplingTauValues.size() != temperatureCouplingGroupNames.size() ||
3117 temperatureCouplingReferenceValues.size() != temperatureCouplingGroupNames.size())
3119 gmx_fatal(FARGS, "Invalid T coupling input: %zu groups, %zu ref-t values and "
3121 temperatureCouplingGroupNames.size(),
3122 temperatureCouplingReferenceValues.size(),
3123 temperatureCouplingTauValues.size());
3126 const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
3127 do_numbering(natoms, groups, temperatureCouplingGroupNames, defaultIndexGroups, gnames,
3128 SimulationAtomGroupType::TemperatureCoupling,
3129 restnm, useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
3130 nr = groups->groups[SimulationAtomGroupType::TemperatureCoupling].size();
3132 snew(ir->opts.nrdf, nr);
3133 snew(ir->opts.tau_t, nr);
3134 snew(ir->opts.ref_t, nr);
3135 if (ir->eI == eiBD && ir->bd_fric == 0)
3137 fprintf(stderr, "bd-fric=0, so tau-t will be used as the inverse friction constant(s)\n");
3140 if (useReferenceTemperature)
3142 if (size_t(nr) != temperatureCouplingReferenceValues.size())
3144 gmx_fatal(FARGS, "Not enough ref-t and tau-t values!");
3148 convertReals(wi, temperatureCouplingTauValues, "tau-t", ir->opts.tau_t);
3149 for (i = 0; (i < nr); i++)
3151 if ((ir->eI == eiBD) && ir->opts.tau_t[i] <= 0)
3153 sprintf(warn_buf, "With integrator %s tau-t should be larger than 0", ei_names[ir->eI]);
3154 warning_error(wi, warn_buf);
3157 if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
3159 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.");
3162 if (ir->opts.tau_t[i] >= 0)
3164 tau_min = std::min(tau_min, ir->opts.tau_t[i]);
3167 if (ir->etc != etcNO && ir->nsttcouple == -1)
3169 ir->nsttcouple = ir_optimal_nsttcouple(ir);
3174 if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
3176 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");
3178 if (ir->epc == epcMTTK)
3180 if (ir->etc != etcNOSEHOOVER)
3182 gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
3186 if (ir->nstpcouple != ir->nsttcouple)
3188 int mincouple = std::min(ir->nstpcouple, ir->nsttcouple);
3189 ir->nstpcouple = ir->nsttcouple = mincouple;
3190 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);
3191 warning_note(wi, warn_buf);
3196 /* velocity verlet with averaged kinetic energy KE = 0.5*(v(t+1/2) - v(t-1/2)) is implemented
3197 primarily for testing purposes, and does not work with temperature coupling other than 1 */
3199 if (ETC_ANDERSEN(ir->etc))
3201 if (ir->nsttcouple != 1)
3204 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");
3205 warning_note(wi, warn_buf);
3208 nstcmin = tcouple_min_integration_steps(ir->etc);
3211 if (tau_min/(ir->delta_t*ir->nsttcouple) < nstcmin - 10*GMX_REAL_EPS)
3213 sprintf(warn_buf, "For proper integration of the %s thermostat, tau-t (%g) should be at least %d times larger than nsttcouple*dt (%g)",
3214 ETCOUPLTYPE(ir->etc),
3216 ir->nsttcouple*ir->delta_t);
3217 warning(wi, warn_buf);
3220 convertReals(wi, temperatureCouplingReferenceValues, "ref-t", ir->opts.ref_t);
3221 for (i = 0; (i < nr); i++)
3223 if (ir->opts.ref_t[i] < 0)
3225 gmx_fatal(FARGS, "ref-t for group %d negative", i);
3228 /* set the lambda mc temperature to the md integrator temperature (which should be defined
3229 if we are in this conditional) if mc_temp is negative */
3230 if (ir->expandedvals->mc_temp < 0)
3232 ir->expandedvals->mc_temp = ir->opts.ref_t[0]; /*for now, set to the first reft */
3236 /* Simulated annealing for each group. There are nr groups */
3237 auto simulatedAnnealingGroupNames = gmx::splitString(is->anneal);
3238 if (simulatedAnnealingGroupNames.size() == 1 &&
3239 gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[0], "N", 1))
3241 simulatedAnnealingGroupNames.resize(0);
3243 if (!simulatedAnnealingGroupNames.empty() &&
3244 gmx::ssize(simulatedAnnealingGroupNames) != nr)
3246 gmx_fatal(FARGS, "Wrong number of annealing values: %zu (for %d groups)\n",
3247 simulatedAnnealingGroupNames.size(), nr);
3251 snew(ir->opts.annealing, nr);
3252 snew(ir->opts.anneal_npoints, nr);
3253 snew(ir->opts.anneal_time, nr);
3254 snew(ir->opts.anneal_temp, nr);
3255 for (i = 0; i < nr; i++)
3257 ir->opts.annealing[i] = eannNO;
3258 ir->opts.anneal_npoints[i] = 0;
3259 ir->opts.anneal_time[i] = nullptr;
3260 ir->opts.anneal_temp[i] = nullptr;
3262 if (!simulatedAnnealingGroupNames.empty())
3265 for (i = 0; i < nr; i++)
3267 if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "N", 1))
3269 ir->opts.annealing[i] = eannNO;
3271 else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "S", 1))
3273 ir->opts.annealing[i] = eannSINGLE;
3276 else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "P", 1))
3278 ir->opts.annealing[i] = eannPERIODIC;
3284 /* Read the other fields too */
3285 auto simulatedAnnealingPoints = gmx::splitString(is->anneal_npoints);
3286 if (simulatedAnnealingPoints.size() != simulatedAnnealingGroupNames.size())
3288 gmx_fatal(FARGS, "Found %zu annealing-npoints values for %zu groups\n",
3289 simulatedAnnealingPoints.size(), simulatedAnnealingGroupNames.size());
3291 convertInts(wi, simulatedAnnealingPoints, "annealing points", ir->opts.anneal_npoints);
3292 size_t numSimulatedAnnealingFields = 0;
3293 for (i = 0; i < nr; i++)
3295 if (ir->opts.anneal_npoints[i] == 1)
3297 gmx_fatal(FARGS, "Please specify at least a start and an end point for annealing\n");
3299 snew(ir->opts.anneal_time[i], ir->opts.anneal_npoints[i]);
3300 snew(ir->opts.anneal_temp[i], ir->opts.anneal_npoints[i]);
3301 numSimulatedAnnealingFields += ir->opts.anneal_npoints[i];
3304 auto simulatedAnnealingTimes = gmx::splitString(is->anneal_time);
3306 if (simulatedAnnealingTimes.size() != numSimulatedAnnealingFields)
3308 gmx_fatal(FARGS, "Found %zu annealing-time values, wanted %zu\n",
3309 simulatedAnnealingTimes.size(), numSimulatedAnnealingFields);
3311 auto simulatedAnnealingTemperatures = gmx::splitString(is->anneal_temp);
3312 if (simulatedAnnealingTemperatures.size() != numSimulatedAnnealingFields)
3314 gmx_fatal(FARGS, "Found %zu annealing-temp values, wanted %zu\n",
3315 simulatedAnnealingTemperatures.size(), numSimulatedAnnealingFields);
3318 std::vector<real> allSimulatedAnnealingTimes(numSimulatedAnnealingFields);
3319 std::vector<real> allSimulatedAnnealingTemperatures(numSimulatedAnnealingFields);
3320 convertReals(wi, simulatedAnnealingTimes, "anneal-time", allSimulatedAnnealingTimes.data());
3321 convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp", allSimulatedAnnealingTemperatures.data());
3322 for (i = 0, k = 0; i < nr; i++)
3324 for (j = 0; j < ir->opts.anneal_npoints[i]; j++)
3326 ir->opts.anneal_time[i][j] = allSimulatedAnnealingTimes[k];
3327 ir->opts.anneal_temp[i][j] = allSimulatedAnnealingTemperatures[k];
3330 if (ir->opts.anneal_time[i][0] > (ir->init_t+GMX_REAL_EPS))
3332 gmx_fatal(FARGS, "First time point for annealing > init_t.\n");
3338 if (ir->opts.anneal_time[i][j] < ir->opts.anneal_time[i][j-1])
3340 gmx_fatal(FARGS, "Annealing timepoints out of order: t=%f comes after t=%f\n",
3341 ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j-1]);
3344 if (ir->opts.anneal_temp[i][j] < 0)
3346 gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n", ir->opts.anneal_temp[i][j]);
3351 /* Print out some summary information, to make sure we got it right */
3352 for (i = 0; i < nr; i++)
3354 if (ir->opts.annealing[i] != eannNO)
3356 j = groups->groups[SimulationAtomGroupType::TemperatureCoupling][i];
3357 fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
3358 *(groups->groupNames[j]), eann_names[ir->opts.annealing[i]],
3359 ir->opts.anneal_npoints[i]);
3360 fprintf(stderr, "Time (ps) Temperature (K)\n");
3361 /* All terms except the last one */
3362 for (j = 0; j < (ir->opts.anneal_npoints[i]-1); j++)
3364 fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3367 /* Finally the last one */
3368 j = ir->opts.anneal_npoints[i]-1;
3369 if (ir->opts.annealing[i] == eannSINGLE)
3371 fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3375 fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]);
3376 if (std::fabs(ir->opts.anneal_temp[i][j]-ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS)
3378 warning_note(wi, "There is a temperature jump when your annealing loops back.\n");
3389 make_pull_groups(ir->pull, is->pull_grp, defaultIndexGroups, gnames);
3391 make_pull_coords(ir->pull);
3396 make_rotation_groups(ir->rot, is->rot_grp, defaultIndexGroups, gnames);
3399 if (ir->eSwapCoords != eswapNO)
3401 make_swap_groups(ir->swap, defaultIndexGroups, gnames);
3404 /* Make indices for IMD session */
3407 make_IMD_group(ir->imd, is->imd_grp, defaultIndexGroups, gnames);
3410 gmx::IndexGroupsAndNames defaultIndexGroupsAndNames(
3411 *defaultIndexGroups, gmx::arrayRefFromArray(gnames, defaultIndexGroups->nr));
3412 notifier.notifier_.notify(defaultIndexGroupsAndNames);
3414 auto accelerations = gmx::splitString(is->acc);
3415 auto accelerationGroupNames = gmx::splitString(is->accgrps);
3416 if (accelerationGroupNames.size() * DIM != accelerations.size())
3418 gmx_fatal(FARGS, "Invalid Acceleration input: %zu groups and %zu acc. values",
3419 accelerationGroupNames.size(), accelerations.size());
3421 do_numbering(natoms, groups, accelerationGroupNames, defaultIndexGroups, gnames,
3422 SimulationAtomGroupType::Acceleration,
3423 restnm, egrptpALL_GENREST, bVerbose, wi);
3424 nr = groups->groups[SimulationAtomGroupType::Acceleration].size();
3425 snew(ir->opts.acc, nr);
3426 ir->opts.ngacc = nr;
3428 convertRvecs(wi, accelerations, "anneal-time", ir->opts.acc);
3430 auto freezeDims = gmx::splitString(is->frdim);
3431 auto freezeGroupNames = gmx::splitString(is->freeze);
3432 if (freezeDims.size() != DIM * freezeGroupNames.size())
3434 gmx_fatal(FARGS, "Invalid Freezing input: %zu groups and %zu freeze values",
3435 freezeGroupNames.size(), freezeDims.size());
3437 do_numbering(natoms, groups, freezeGroupNames, defaultIndexGroups, gnames,
3438 SimulationAtomGroupType::Freeze,
3439 restnm, egrptpALL_GENREST, bVerbose, wi);
3440 nr = groups->groups[SimulationAtomGroupType::Freeze].size();
3441 ir->opts.ngfrz = nr;
3442 snew(ir->opts.nFreeze, nr);
3443 for (i = k = 0; (size_t(i) < freezeGroupNames.size()); i++)
3445 for (j = 0; (j < DIM); j++, k++)
3447 ir->opts.nFreeze[i][j] = static_cast<int>(gmx::equalCaseInsensitive(freezeDims[k], "Y", 1));
3448 if (!ir->opts.nFreeze[i][j])
3450 if (!gmx::equalCaseInsensitive(freezeDims[k], "N", 1))
3452 sprintf(warnbuf, "Please use Y(ES) or N(O) for freezedim only "
3453 "(not %s)", freezeDims[k].c_str());
3454 warning(wi, warn_buf);
3459 for (; (i < nr); i++)
3461 for (j = 0; (j < DIM); j++)
3463 ir->opts.nFreeze[i][j] = 0;
3467 auto energyGroupNames = gmx::splitString(is->energy);
3468 do_numbering(natoms, groups, energyGroupNames, defaultIndexGroups, gnames,
3469 SimulationAtomGroupType::EnergyOutput,
3470 restnm, egrptpALL_GENREST, bVerbose, wi);
3471 add_wall_energrps(groups, ir->nwall, symtab);
3472 ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
3473 auto vcmGroupNames = gmx::splitString(is->vcm);
3475 do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames,
3476 SimulationAtomGroupType::MassCenterVelocityRemoval,
3477 restnm, vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
3480 warning(wi, "Some atoms are not part of any center of mass motion removal group.\n"
3481 "This may lead to artifacts.\n"
3482 "In most cases one should use one group for the whole system.");
3485 /* Now we have filled the freeze struct, so we can calculate NRDF */
3486 calc_nrdf(mtop, ir, gnames);
3488 auto user1GroupNames = gmx::splitString(is->user1);
3489 do_numbering(natoms, groups, user1GroupNames, defaultIndexGroups, gnames,
3490 SimulationAtomGroupType::User1,
3491 restnm, egrptpALL_GENREST, bVerbose, wi);
3492 auto user2GroupNames = gmx::splitString(is->user2);
3493 do_numbering(natoms, groups, user2GroupNames, defaultIndexGroups, gnames,
3494 SimulationAtomGroupType::User2,
3495 restnm, egrptpALL_GENREST, bVerbose, wi);
3496 auto compressedXGroupNames = gmx::splitString(is->x_compressed_groups);
3497 do_numbering(natoms, groups, compressedXGroupNames, defaultIndexGroups, gnames,
3498 SimulationAtomGroupType::CompressedPositionOutput,
3499 restnm, egrptpONE, bVerbose, wi);
3500 auto orirefFitGroupNames = gmx::splitString(is->orirefitgrp);
3501 do_numbering(natoms, groups, orirefFitGroupNames, defaultIndexGroups, gnames,
3502 SimulationAtomGroupType::OrientationRestraintsFit,
3503 restnm, egrptpALL_GENREST, bVerbose, wi);
3505 /* QMMM input processing */
3506 auto qmGroupNames = gmx::splitString(is->QMMM);
3507 auto qmMethods = gmx::splitString(is->QMmethod);
3508 auto qmBasisSets = gmx::splitString(is->QMbasis);
3509 if (ir->eI != eiMimic)
3511 if (qmMethods.size() != qmGroupNames.size() ||
3512 qmBasisSets.size() != qmGroupNames.size())
3514 gmx_fatal(FARGS, "Invalid QMMM input: %zu groups %zu basissets"
3515 " and %zu methods\n", qmGroupNames.size(),
3516 qmBasisSets.size(), qmMethods.size());
3518 /* group rest, if any, is always MM! */
3519 do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
3520 SimulationAtomGroupType::QuantumMechanics,
3521 restnm, egrptpALL_GENREST, bVerbose, wi);
3522 nr = qmGroupNames.size(); /*atoms->grps[egcQMMM].nr;*/
3523 ir->opts.ngQM = qmGroupNames.size();
3524 snew(ir->opts.QMmethod, nr);
3525 snew(ir->opts.QMbasis, nr);
3526 for (i = 0; i < nr; i++)
3528 /* input consists of strings: RHF CASSCF PM3 .. These need to be
3529 * converted to the corresponding enum in names.c
3531 ir->opts.QMmethod[i] = search_QMstring(qmMethods[i].c_str(),
3534 ir->opts.QMbasis[i] = search_QMstring(qmBasisSets[i].c_str(),
3539 auto qmMultiplicities = gmx::splitString(is->QMmult);
3540 auto qmCharges = gmx::splitString(is->QMcharge);
3541 auto qmbSH = gmx::splitString(is->bSH);
3542 snew(ir->opts.QMmult, nr);
3543 snew(ir->opts.QMcharge, nr);
3544 snew(ir->opts.bSH, nr);
3545 convertInts(wi, qmMultiplicities, "QMmult", ir->opts.QMmult);
3546 convertInts(wi, qmCharges, "QMcharge", ir->opts.QMcharge);
3547 convertYesNos(wi, qmbSH, "bSH", ir->opts.bSH);
3549 auto CASelectrons = gmx::splitString(is->CASelectrons);
3550 auto CASorbitals = gmx::splitString(is->CASorbitals);
3551 snew(ir->opts.CASelectrons, nr);
3552 snew(ir->opts.CASorbitals, nr);
3553 convertInts(wi, CASelectrons, "CASelectrons", ir->opts.CASelectrons);
3554 convertInts(wi, CASorbitals, "CASOrbitals", ir->opts.CASorbitals);
3556 auto SAon = gmx::splitString(is->SAon);
3557 auto SAoff = gmx::splitString(is->SAoff);
3558 auto SAsteps = gmx::splitString(is->SAsteps);
3559 snew(ir->opts.SAon, nr);
3560 snew(ir->opts.SAoff, nr);
3561 snew(ir->opts.SAsteps, nr);
3562 convertInts(wi, SAon, "SAon", ir->opts.SAon);
3563 convertInts(wi, SAoff, "SAoff", ir->opts.SAoff);
3564 convertInts(wi, SAsteps, "SAsteps", ir->opts.SAsteps);
3569 if (qmGroupNames.size() > 1)
3571 gmx_fatal(FARGS, "Currently, having more than one QM group in MiMiC is not supported");
3573 /* group rest, if any, is always MM! */
3574 do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
3575 SimulationAtomGroupType::QuantumMechanics,
3576 restnm, egrptpALL_GENREST, bVerbose, wi);
3578 ir->opts.ngQM = qmGroupNames.size();
3581 /* end of QMMM input */
3585 for (auto group : gmx::keysOf(groups->groups))
3587 fprintf(stderr, "%-16s has %zu element(s):", shortName(group), groups->groups[group].size());
3588 for (const auto &entry : groups->groups[group])
3590 fprintf(stderr, " %s", *(groups->groupNames[entry]));
3592 fprintf(stderr, "\n");
3596 nr = groups->groups[SimulationAtomGroupType::EnergyOutput].size();
3597 snew(ir->opts.egp_flags, nr*nr);
3599 bExcl = do_egp_flag(ir, groups, "energygrp-excl", is->egpexcl, EGP_EXCL);
3600 if (bExcl && ir->cutoff_scheme == ecutsVERLET)
3602 warning_error(wi, "Energy group exclusions are not (yet) implemented for the Verlet scheme");
3604 if (bExcl && EEL_FULL(ir->coulombtype))
3606 warning(wi, "Can not exclude the lattice Coulomb energy between energy groups");
3609 bTable = do_egp_flag(ir, groups, "energygrp-table", is->egptable, EGP_TABLE);
3610 if (bTable && !(ir->vdwtype == evdwUSER) &&
3611 !(ir->coulombtype == eelUSER) && !(ir->coulombtype == eelPMEUSER) &&
3612 !(ir->coulombtype == eelPMEUSERSWITCH))
3614 gmx_fatal(FARGS, "Can only have energy group pair tables in combination with user tables for VdW and/or Coulomb");
3617 /* final check before going out of scope if simulated tempering variables
3618 * need to be set to default values.
3620 if ((ir->expandedvals->nstexpanded < 0) && ir->bSimTemp)
3622 ir->expandedvals->nstexpanded = 2*static_cast<int>(ir->opts.tau_t[0]/ir->delta_t);
3623 warning(wi, gmx::formatString("the value for nstexpanded was not specified for "
3624 " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
3625 "by default, but it is recommended to set it to an explicit value!",
3626 ir->expandedvals->nstexpanded));
3628 for (i = 0; (i < defaultIndexGroups->nr); i++)
3633 done_blocka(defaultIndexGroups);
3634 sfree(defaultIndexGroups);
3640 static void check_disre(const gmx_mtop_t *mtop)
3642 if (gmx_mtop_ftype_count(mtop, F_DISRES) > 0)
3644 const gmx_ffparams_t &ffparams = mtop->ffparams;
3647 for (int i = 0; i < ffparams.numTypes(); i++)
3649 int ftype = ffparams.functype[i];
3650 if (ftype == F_DISRES)
3652 int label = ffparams.iparams[i].disres.label;
3653 if (label == old_label)
3655 fprintf(stderr, "Distance restraint index %d occurs twice\n", label);
3663 gmx_fatal(FARGS, "Found %d double distance restraint indices,\n"
3664 "probably the parameters for multiple pairs in one restraint "
3665 "are not identical\n", ndouble);
3670 static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys,
3675 gmx_mtop_ilistloop_t iloop;
3684 for (d = 0; d < DIM; d++)
3686 AbsRef[d] = (d < ndof_com(ir) ? 0 : 1);
3688 /* Check for freeze groups */
3689 for (g = 0; g < ir->opts.ngfrz; g++)
3691 for (d = 0; d < DIM; d++)
3693 if (ir->opts.nFreeze[g][d] != 0)
3701 /* Check for position restraints */
3702 iloop = gmx_mtop_ilistloop_init(sys);
3703 while (const InteractionLists *ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
3706 (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
3708 for (i = 0; i < (*ilist)[F_POSRES].size(); i += 2)
3710 pr = &sys->ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]];
3711 for (d = 0; d < DIM; d++)
3713 if (pr->posres.fcA[d] != 0)
3719 for (i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2)
3721 /* Check for flat-bottom posres */
3722 pr = &sys->ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]];
3723 if (pr->fbposres.k != 0)
3725 switch (pr->fbposres.geom)
3727 case efbposresSPHERE:
3728 AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1;
3730 case efbposresCYLINDERX:
3731 AbsRef[YY] = AbsRef[ZZ] = 1;
3733 case efbposresCYLINDERY:
3734 AbsRef[XX] = AbsRef[ZZ] = 1;
3736 case efbposresCYLINDER:
3737 /* efbposres is a synonym for efbposresCYLINDERZ for backwards compatibility */
3738 case efbposresCYLINDERZ:
3739 AbsRef[XX] = AbsRef[YY] = 1;
3741 case efbposresX: /* d=XX */
3742 case efbposresY: /* d=YY */
3743 case efbposresZ: /* d=ZZ */
3744 d = pr->fbposres.geom - efbposresX;
3748 gmx_fatal(FARGS, " Invalid geometry for flat-bottom position restraint.\n"
3749 "Expected nr between 1 and %d. Found %d\n", efbposresNR-1,
3757 return (AbsRef[XX] != 0 && AbsRef[YY] != 0 && AbsRef[ZZ] != 0);
3761 check_combination_rule_differences(const gmx_mtop_t *mtop, int state,
3762 bool *bC6ParametersWorkWithGeometricRules,
3763 bool *bC6ParametersWorkWithLBRules,
3764 bool *bLBRulesPossible)
3766 int ntypes, tpi, tpj;
3769 double c6i, c6j, c12i, c12j;
3770 double c6, c6_geometric, c6_LB;
3771 double sigmai, sigmaj, epsi, epsj;
3772 bool bCanDoLBRules, bCanDoGeometricRules;
3775 /* A tolerance of 1e-5 seems reasonable for (possibly hand-typed)
3776 * force-field floating point parameters.
3779 ptr = getenv("GMX_LJCOMB_TOL");
3783 double gmx_unused canary;
3785 if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
3787 gmx_fatal(FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr);
3792 *bC6ParametersWorkWithLBRules = TRUE;
3793 *bC6ParametersWorkWithGeometricRules = TRUE;
3794 bCanDoLBRules = TRUE;
3795 ntypes = mtop->ffparams.atnr;
3796 snew(typecount, ntypes);
3797 gmx_mtop_count_atomtypes(mtop, state, typecount);
3798 *bLBRulesPossible = TRUE;
3799 for (tpi = 0; tpi < ntypes; ++tpi)
3801 c6i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c6;
3802 c12i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c12;
3803 for (tpj = tpi; tpj < ntypes; ++tpj)
3805 c6j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c6;
3806 c12j = mtop->ffparams.iparams[(ntypes + 1) * tpj].lj.c12;
3807 c6 = mtop->ffparams.iparams[ntypes * tpi + tpj].lj.c6;
3808 c6_geometric = std::sqrt(c6i * c6j);
3809 if (!gmx_numzero(c6_geometric))
3811 if (!gmx_numzero(c12i) && !gmx_numzero(c12j))
3813 sigmai = gmx::sixthroot(c12i / c6i);
3814 sigmaj = gmx::sixthroot(c12j / c6j);
3815 epsi = c6i * c6i /(4.0 * c12i);
3816 epsj = c6j * c6j /(4.0 * c12j);
3817 c6_LB = 4.0 * std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj));
3821 *bLBRulesPossible = FALSE;
3822 c6_LB = c6_geometric;
3824 bCanDoLBRules = gmx_within_tol(c6_LB, c6, tol);
3829 *bC6ParametersWorkWithLBRules = FALSE;
3832 bCanDoGeometricRules = gmx_within_tol(c6_geometric, c6, tol);
3834 if (!bCanDoGeometricRules)
3836 *bC6ParametersWorkWithGeometricRules = FALSE;
3844 check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop,
3847 bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules;
3849 check_combination_rule_differences(mtop, 0,
3850 &bC6ParametersWorkWithGeometricRules,
3851 &bC6ParametersWorkWithLBRules,
3853 if (ir->ljpme_combination_rule == eljpmeLB)
3855 if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
3857 warning(wi, "You are using arithmetic-geometric combination rules "
3858 "in LJ-PME, but your non-bonded C6 parameters do not "
3859 "follow these rules.");
3864 if (!bC6ParametersWorkWithGeometricRules)
3866 if (ir->eDispCorr != edispcNO)
3868 warning_note(wi, "You are using geometric combination rules in "
3869 "LJ-PME, but your non-bonded C6 parameters do "
3870 "not follow these rules. "
3871 "This will introduce very small errors in the forces and energies in "
3872 "your simulations. Dispersion correction will correct total energy "
3873 "and/or pressure for isotropic systems, but not forces or surface tensions.");
3877 warning_note(wi, "You are using geometric combination rules in "
3878 "LJ-PME, but your non-bonded C6 parameters do "
3879 "not follow these rules. "
3880 "This will introduce very small errors in the forces and energies in "
3881 "your simulations. If your system is homogeneous, consider using dispersion correction "
3882 "for the total energy and pressure.");
3888 void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
3891 char err_buf[STRLEN];
3896 gmx_mtop_atomloop_block_t aloopb;
3898 char warn_buf[STRLEN];
3900 set_warning_line(wi, mdparin, -1);
3902 if (ir->cutoff_scheme == ecutsVERLET &&
3903 ir->verletbuf_tol > 0 &&
3905 ((EI_MD(ir->eI) || EI_SD(ir->eI)) &&
3906 (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
3908 /* Check if a too small Verlet buffer might potentially
3909 * cause more drift than the thermostat can couple off.
3911 /* Temperature error fraction for warning and suggestion */
3912 const real T_error_warn = 0.002;
3913 const real T_error_suggest = 0.001;
3914 /* For safety: 2 DOF per atom (typical with constraints) */
3915 const real nrdf_at = 2;
3916 real T, tau, max_T_error;
3921 for (i = 0; i < ir->opts.ngtc; i++)
3923 T = std::max(T, ir->opts.ref_t[i]);
3924 tau = std::max(tau, ir->opts.tau_t[i]);
3928 /* This is a worst case estimate of the temperature error,
3929 * assuming perfect buffer estimation and no cancelation
3930 * of errors. The factor 0.5 is because energy distributes
3931 * equally over Ekin and Epot.
3933 max_T_error = 0.5*tau*ir->verletbuf_tol/(nrdf_at*BOLTZ*T);
3934 if (max_T_error > T_error_warn)
3936 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.",
3937 ir->verletbuf_tol, T, tau,
3939 100*T_error_suggest,
3940 ir->verletbuf_tol*T_error_suggest/max_T_error);
3941 warning(wi, warn_buf);
3946 if (ETC_ANDERSEN(ir->etc))
3950 for (i = 0; i < ir->opts.ngtc; i++)
3952 sprintf(err_buf, "all tau_t must currently be equal using Andersen temperature control, violated for group %d", i);
3953 CHECK(ir->opts.tau_t[0] != ir->opts.tau_t[i]);
3954 sprintf(err_buf, "all tau_t must be positive using Andersen temperature control, tau_t[%d]=%10.6f",
3955 i, ir->opts.tau_t[i]);
3956 CHECK(ir->opts.tau_t[i] < 0);
3959 if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
3961 for (i = 0; i < ir->opts.ngtc; i++)
3963 int nsteps = gmx::roundToInt(ir->opts.tau_t[i]/ir->delta_t);
3964 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);
3965 CHECK(nsteps % ir->nstcomm != 0);
3970 if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD &&
3971 ir->comm_mode == ecmNO &&
3972 !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) &&
3973 !ETC_ANDERSEN(ir->etc))
3975 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");
3978 if (ir->epc == epcPARRINELLORAHMAN &&
3979 ir->etc == etcNOSEHOOVER)
3982 for (int g = 0; g < ir->opts.ngtc; g++)
3984 tau_t_max = std::max(tau_t_max, ir->opts.tau_t[g]);
3986 if (ir->tau_p < 1.9*tau_t_max)
3988 std::string message =
3989 gmx::formatString("With %s T-coupling and %s p-coupling, "
3990 "%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
3991 etcoupl_names[ir->etc],
3992 epcoupl_names[ir->epc],
3994 "tau-t", tau_t_max);
3995 warning(wi, message.c_str());
3999 /* Check for pressure coupling with absolute position restraints */
4000 if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
4002 absolute_reference(ir, sys, TRUE, AbsRef);
4004 for (m = 0; m < DIM; m++)
4006 if (AbsRef[m] && norm2(ir->compress[m]) > 0)
4008 warning(wi, "You are using pressure coupling with absolute position restraints, this will give artifacts. Use the refcoord_scaling option.");
4016 aloopb = gmx_mtop_atomloop_block_init(sys);
4018 while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol))
4020 if (atom->q != 0 || atom->qB != 0)
4028 if (EEL_FULL(ir->coulombtype))
4031 "You are using full electrostatics treatment %s for a system without charges.\n"
4032 "This costs a lot of performance for just processing zeros, consider using %s instead.\n",
4033 EELTYPE(ir->coulombtype), EELTYPE(eelCUT));
4034 warning(wi, err_buf);
4039 if (ir->coulombtype == eelCUT && ir->rcoulomb > 0)
4042 "You are using a plain Coulomb cut-off, which might produce artifacts.\n"
4043 "You might want to consider using %s electrostatics.\n",
4045 warning_note(wi, err_buf);
4049 /* Check if combination rules used in LJ-PME are the same as in the force field */
4050 if (EVDW_PME(ir->vdwtype))
4052 check_combination_rules(ir, sys, wi);
4055 /* Generalized reaction field */
4056 if (ir->coulombtype == eelGRF_NOTUSED)
4058 warning_error(wi, "Generalized reaction-field electrostatics is no longer supported. "
4059 "You can use normal reaction-field instead and compute the reaction-field constant by hand.");
4063 for (int i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
4065 for (m = 0; (m < DIM); m++)
4067 if (fabs(ir->opts.acc[i][m]) > 1e-6)
4076 snew(mgrp, sys->groups.groups[SimulationAtomGroupType::Acceleration].size());
4077 for (const AtomProxy atomP : AtomRange(*sys))
4079 const t_atom &local = atomP.atom();
4080 int i = atomP.globalAtomNumber();
4081 mgrp[getGroupType(sys->groups, SimulationAtomGroupType::Acceleration, i)] += local.m;
4084 for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
4086 for (m = 0; (m < DIM); m++)
4088 acc[m] += ir->opts.acc[i][m]*mgrp[i];
4092 for (m = 0; (m < DIM); m++)
4094 if (fabs(acc[m]) > 1e-6)
4096 const char *dim[DIM] = { "X", "Y", "Z" };
4098 "Net Acceleration in %s direction, will %s be corrected\n",
4099 dim[m], ir->nstcomm != 0 ? "" : "not");
4100 if (ir->nstcomm != 0 && m < ndof_com(ir))
4103 for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++)
4105 ir->opts.acc[i][m] -= acc[m];
4113 if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0 &&
4114 !gmx_within_tol(sys->ffparams.reppow, 12.0, 10*GMX_DOUBLE_EPS))
4116 gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12");
4124 for (i = 0; i < ir->pull->ncoord && !bWarned; i++)
4126 if (ir->pull->coord[i].group[0] == 0 ||
4127 ir->pull->coord[i].group[1] == 0)
4129 absolute_reference(ir, sys, FALSE, AbsRef);
4130 for (m = 0; m < DIM; m++)
4132 if (ir->pull->coord[i].dim[m] && !AbsRef[m])
4134 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.");
4142 for (i = 0; i < 3; i++)
4144 for (m = 0; m <= i; m++)
4146 if ((ir->epc != epcNO && ir->compress[i][m] != 0) ||
4147 ir->deform[i][m] != 0)
4149 for (c = 0; c < ir->pull->ncoord; c++)
4151 if (ir->pull->coord[c].eGeom == epullgDIRPBC &&
4152 ir->pull->coord[c].vec[m] != 0)
4154 gmx_fatal(FARGS, "Can not have dynamic box while using pull geometry '%s' (dim %c)", EPULLGEOM(ir->pull->coord[c].eGeom), 'x'+m);
4165 void double_check(t_inputrec *ir, matrix box,
4166 bool bHasNormalConstraints,
4167 bool bHasAnyConstraints,
4170 char warn_buf[STRLEN];
4173 ptr = check_box(ir->ePBC, box);
4176 warning_error(wi, ptr);
4179 if (bHasNormalConstraints && ir->eConstrAlg == econtSHAKE)
4181 if (ir->shake_tol <= 0.0)
4183 sprintf(warn_buf, "ERROR: shake-tol must be > 0 instead of %g\n",
4185 warning_error(wi, warn_buf);
4189 if ( (ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
4191 /* If we have Lincs constraints: */
4192 if (ir->eI == eiMD && ir->etc == etcNO &&
4193 ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
4195 sprintf(warn_buf, "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
4196 warning_note(wi, warn_buf);
4199 if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8))
4201 sprintf(warn_buf, "For accurate %s with LINCS constraints, lincs-order should be 8 or more.", ei_names[ir->eI]);
4202 warning_note(wi, warn_buf);
4204 if (ir->epc == epcMTTK)
4206 warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
4210 if (bHasAnyConstraints && ir->epc == epcMTTK)
4212 warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
4215 if (ir->LincsWarnAngle > 90.0)
4217 sprintf(warn_buf, "lincs-warnangle can not be larger than 90 degrees, setting it to 90.\n");
4218 warning(wi, warn_buf);
4219 ir->LincsWarnAngle = 90.0;
4222 if (ir->ePBC != epbcNONE)
4224 if (ir->nstlist == 0)
4226 warning(wi, "With nstlist=0 atoms are only put into the box at step 0, therefore drifting atoms might cause the simulation to crash.");
4228 if (gmx::square(ir->rlist) >= max_cutoff2(ir->ePBC, box))
4230 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");
4231 warning_error(wi, warn_buf);
4236 void check_chargegroup_radii(const gmx_mtop_t *mtop, const t_inputrec *ir,
4240 real rvdw1, rvdw2, rcoul1, rcoul2;
4241 char warn_buf[STRLEN];
4243 calc_chargegroup_radii(mtop, x, &rvdw1, &rvdw2, &rcoul1, &rcoul2);
4247 printf("Largest charge group radii for Van der Waals: %5.3f, %5.3f nm\n",
4252 printf("Largest charge group radii for Coulomb: %5.3f, %5.3f nm\n",
4258 if (rvdw1 + rvdw2 > ir->rlist ||
4259 rcoul1 + rcoul2 > ir->rlist)
4262 "The sum of the two largest charge group radii (%f) "
4263 "is larger than rlist (%f)\n",
4264 std::max(rvdw1+rvdw2, rcoul1+rcoul2), ir->rlist);
4265 warning(wi, warn_buf);
4269 /* Here we do not use the zero at cut-off macro,
4270 * since user defined interactions might purposely
4271 * not be zero at the cut-off.
4273 if (ir_vdw_is_zero_at_cutoff(ir) &&
4274 rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
4276 sprintf(warn_buf, "The sum of the two largest charge group "
4277 "radii (%f) is larger than rlist (%f) - rvdw (%f).\n"
4278 "With exact cut-offs, better performance can be "
4279 "obtained with cutoff-scheme = %s, because it "
4280 "does not use charge groups at all.",
4282 ir->rlist, ir->rvdw,
4283 ecutscheme_names[ecutsVERLET]);
4286 warning(wi, warn_buf);
4290 warning_note(wi, warn_buf);
4293 if (ir_coulomb_is_zero_at_cutoff(ir) &&
4294 rcoul1 + rcoul2 > ir->rlist - ir->rcoulomb)
4296 sprintf(warn_buf, "The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rcoulomb (%f).\n"
4297 "With exact cut-offs, better performance can be obtained with cutoff-scheme = %s, because it does not use charge groups at all.",
4299 ir->rlist, ir->rcoulomb,
4300 ecutscheme_names[ecutsVERLET]);
4303 warning(wi, warn_buf);
4307 warning_note(wi, warn_buf);