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/fileio/warninp.h"
50 #include "gromacs/gmxpreprocess/gpp_atomtype.h"
51 #include "gromacs/gmxpreprocess/gpp_bond_atomtype.h"
52 #include "gromacs/gmxpreprocess/grompp_impl.h"
53 #include "gromacs/gmxpreprocess/notset.h"
54 #include "gromacs/gmxpreprocess/readir.h"
55 #include "gromacs/gmxpreprocess/topdirs.h"
56 #include "gromacs/gmxpreprocess/toputil.h"
57 #include "gromacs/math/functions.h"
58 #include "gromacs/mdtypes/md_enums.h"
59 #include "gromacs/topology/exclusionblocks.h"
60 #include "gromacs/topology/ifunc.h"
61 #include "gromacs/topology/symtab.h"
62 #include "gromacs/utility/arrayref.h"
63 #include "gromacs/utility/cstringutil.h"
64 #include "gromacs/utility/fatalerror.h"
65 #include "gromacs/utility/gmxassert.h"
66 #include "gromacs/utility/smalloc.h"
67 #include "gromacs/utility/stringutil.h"
69 void generate_nbparams(int comb,
71 InteractionTypeParameters *plist,
72 PreprocessingAtomTypes *atypes,
76 real c, bi, bj, ci, cj, ci0, ci1, ci2, cj0, cj1, cj2;
78 /* Lean mean shortcuts */
81 plist->interactionTypes.clear();
83 std::array<real, MAXFORCEPARAM> forceParam = {NOTSET};
84 /* Fill the matrix with force parameters */
92 for (int i = 0; (i < nr); i++)
94 for (int j = 0; (j < nr); j++)
96 for (int nf = 0; (nf < nrfp); nf++)
98 ci = atypes->atomNonBondedParamFromAtomType(i, nf);
99 cj = atypes->atomNonBondedParamFromAtomType(j, nf);
100 c = std::sqrt(ci * cj);
103 plist->interactionTypes.emplace_back(InteractionType({}, forceParam));
108 case eCOMB_ARITHMETIC:
109 /* c0 and c1 are sigma and epsilon */
110 for (int i = 0; (i < nr); i++)
112 for (int j = 0; (j < nr); j++)
114 ci0 = atypes->atomNonBondedParamFromAtomType(i, 0);
115 cj0 = atypes->atomNonBondedParamFromAtomType(j, 0);
116 ci1 = atypes->atomNonBondedParamFromAtomType(i, 1);
117 cj1 = atypes->atomNonBondedParamFromAtomType(j, 1);
118 forceParam[0] = (fabs(ci0) + fabs(cj0))*0.5;
119 /* Negative sigma signals that c6 should be set to zero later,
120 * so we need to propagate that through the combination rules.
122 if (ci0 < 0 || cj0 < 0)
126 forceParam[1] = std::sqrt(ci1*cj1);
127 plist->interactionTypes.emplace_back(InteractionType({}, forceParam));
132 case eCOMB_GEOM_SIG_EPS:
133 /* c0 and c1 are sigma and epsilon */
134 for (int i = 0; (i < nr); i++)
136 for (int j = 0; (j < nr); j++)
138 ci0 = atypes->atomNonBondedParamFromAtomType(i, 0);
139 cj0 = atypes->atomNonBondedParamFromAtomType(j, 0);
140 ci1 = atypes->atomNonBondedParamFromAtomType(i, 1);
141 cj1 = atypes->atomNonBondedParamFromAtomType(j, 1);
142 forceParam[0] = std::sqrt(std::fabs(ci0*cj0));
143 /* Negative sigma signals that c6 should be set to zero later,
144 * so we need to propagate that through the combination rules.
146 if (ci0 < 0 || cj0 < 0)
150 forceParam[1] = std::sqrt(ci1*cj1);
151 plist->interactionTypes.emplace_back(InteractionType({}, forceParam));
157 auto message = gmx::formatString("No such combination rule %d", comb);
158 warning_error_and_exit(wi, message, FARGS);
163 /* Buckingham rules */
164 for (int i = 0; (i < nr); i++)
166 for (int j = 0; (j < nr); j++)
168 ci0 = atypes->atomNonBondedParamFromAtomType(i, 0);
169 cj0 = atypes->atomNonBondedParamFromAtomType(j, 0);
170 ci2 = atypes->atomNonBondedParamFromAtomType(i, 2);
171 cj2 = atypes->atomNonBondedParamFromAtomType(j, 2);
172 bi = atypes->atomNonBondedParamFromAtomType(i, 1);
173 bj = atypes->atomNonBondedParamFromAtomType(j, 1);
174 forceParam[0] = std::sqrt(ci0 * cj0);
175 if ((bi == 0) || (bj == 0))
181 forceParam[1] = 2.0/(1/bi+1/bj);
183 forceParam[2] = std::sqrt(ci2 * cj2);
184 plist->interactionTypes.emplace_back(InteractionType({}, forceParam));
190 auto message = gmx::formatString("Invalid nonbonded type %s",
191 interaction_function[ftype].longname);
192 warning_error(wi, message);
196 /*! \brief Used to temporarily store the explicit non-bonded parameter
197 * combinations, which will be copied to InteractionTypeParameters. */
200 //! Has this combination been set.
202 //! The non-bonded parameters
206 static void realloc_nb_params(PreprocessingAtomTypes *atypes,
207 t_nbparam ***nbparam, t_nbparam ***pair)
209 /* Add space in the non-bonded parameters matrix */
210 int atnr = atypes->size();
211 srenew(*nbparam, atnr);
212 snew((*nbparam)[atnr-1], atnr);
216 snew((*pair)[atnr-1], atnr);
220 int copy_nbparams(t_nbparam **param, int ftype, InteractionTypeParameters *plist, int nr)
227 for (int i = 0; i < nr; i++)
229 for (int j = 0; j <= i; j++)
231 GMX_RELEASE_ASSERT(param, "Must have valid parameters");
232 if (param[i][j].bSet)
234 for (int f = 0; f < nrfp; f++)
236 plist->interactionTypes[nr*i+j].setForceParameter(f, param[i][j].c[f]);
237 plist->interactionTypes[nr*j+i].setForceParameter(f, param[i][j].c[f]);
247 void free_nbparam(t_nbparam **param, int nr)
251 GMX_RELEASE_ASSERT(param, "Must have valid parameters");
252 for (i = 0; i < nr; i++)
254 GMX_RELEASE_ASSERT(param[i], "Must have valid parameters");
260 static void copy_B_from_A(int ftype, double *c)
264 nrfpA = NRFPA(ftype);
265 nrfpB = NRFPB(ftype);
267 /* Copy the B parameters from the first nrfpB A parameters */
268 for (i = 0; (i < nrfpB); i++)
274 void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAtomType *bondAtomType,
275 char *line, int nb_funct,
276 t_nbparam ***nbparam, t_nbparam ***pair,
283 t_xlate xl[eptNR] = {
291 int nr, nfields, j, pt, nfp0 = -1;
292 int batype_nr, nread;
293 char type[STRLEN], btype[STRLEN], ptype[STRLEN];
295 double c[MAXFORCEPARAM];
296 char tmpfield[12][100]; /* Max 12 fields of width 100 */
299 bool have_atomic_number;
300 bool have_bonded_type;
304 /* First assign input line to temporary array */
305 nfields = sscanf(line, "%s%s%s%s%s%s%s%s%s%s%s%s",
306 tmpfield[0], tmpfield[1], tmpfield[2], tmpfield[3], tmpfield[4], tmpfield[5],
307 tmpfield[6], tmpfield[7], tmpfield[8], tmpfield[9], tmpfield[10], tmpfield[11]);
309 /* Comments on optional fields in the atomtypes section:
311 * The force field format is getting a bit old. For OPLS-AA we needed
312 * to add a special bonded atomtype, and for Gerrit Groenhofs QM/MM stuff
313 * we also needed the atomic numbers.
314 * To avoid making all old or user-generated force fields unusable we
315 * have introduced both these quantities as optional columns, and do some
316 * acrobatics to check whether they are present or not.
317 * This will all look much nicer when we switch to XML... sigh.
319 * Field 0 (mandatory) is the nonbonded type name. (string)
320 * Field 1 (optional) is the bonded type (string)
321 * Field 2 (optional) is the atomic number (int)
322 * Field 3 (mandatory) is the mass (numerical)
323 * Field 4 (mandatory) is the charge (numerical)
324 * Field 5 (mandatory) is the particle type (single character)
325 * This is followed by a number of nonbonded parameters.
327 * The safest way to identify the format is the particle type field.
329 * So, here is what we do:
331 * A. Read in the first six fields as strings
332 * B. If field 3 (starting from 0) is a single char, we have neither
333 * bonded_type or atomic numbers.
334 * C. If field 5 is a single char we have both.
335 * D. If field 4 is a single char we check field 1. If this begins with
336 * an alphabetical character we have bonded types, otherwise atomic numbers.
345 if ( (strlen(tmpfield[5]) == 1) && isalpha(tmpfield[5][0]) )
347 have_bonded_type = TRUE;
348 have_atomic_number = TRUE;
350 else if ( (strlen(tmpfield[3]) == 1) && isalpha(tmpfield[3][0]) )
352 have_bonded_type = FALSE;
353 have_atomic_number = FALSE;
357 have_bonded_type = ( isalpha(tmpfield[1][0]) != 0 );
358 have_atomic_number = !have_bonded_type;
361 /* optional fields */
370 if (have_atomic_number)
372 if (have_bonded_type)
374 nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf",
375 type, btype, &atomnr, &m, &q, ptype, &c[0], &c[1]);
384 /* have_atomic_number && !have_bonded_type */
385 nread = sscanf(line, "%s%d%lf%lf%s%lf%lf",
386 type, &atomnr, &m, &q, ptype, &c[0], &c[1]);
396 if (have_bonded_type)
398 /* !have_atomic_number && have_bonded_type */
399 nread = sscanf(line, "%s%s%lf%lf%s%lf%lf",
400 type, btype, &m, &q, ptype, &c[0], &c[1]);
409 /* !have_atomic_number && !have_bonded_type */
410 nread = sscanf(line, "%s%lf%lf%s%lf%lf",
411 type, &m, &q, ptype, &c[0], &c[1]);
420 if (!have_bonded_type)
425 if (!have_atomic_number)
435 if (have_atomic_number)
437 if (have_bonded_type)
439 nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf%lf",
440 type, btype, &atomnr, &m, &q, ptype, &c[0], &c[1], &c[2]);
449 /* have_atomic_number && !have_bonded_type */
450 nread = sscanf(line, "%s%d%lf%lf%s%lf%lf%lf",
451 type, &atomnr, &m, &q, ptype, &c[0], &c[1], &c[2]);
461 if (have_bonded_type)
463 /* !have_atomic_number && have_bonded_type */
464 nread = sscanf(line, "%s%s%lf%lf%s%lf%lf%lf",
465 type, btype, &m, &q, ptype, &c[0], &c[1], &c[2]);
474 /* !have_atomic_number && !have_bonded_type */
475 nread = sscanf(line, "%s%lf%lf%s%lf%lf%lf",
476 type, &m, &q, ptype, &c[0], &c[1], &c[2]);
485 if (!have_bonded_type)
490 if (!have_atomic_number)
498 auto message = gmx::formatString("Invalid function type %d in push_at", nb_funct);
499 warning_error_and_exit(wi, message, FARGS);
501 for (int j = nfp0; (j < MAXFORCEPARAM); j++)
505 std::array<real, MAXFORCEPARAM> forceParam;
507 if (strlen(type) == 1 && isdigit(type[0]))
509 warning_error_and_exit(wi, "Atom type names can't be single digits.", FARGS);
512 if (strlen(btype) == 1 && isdigit(btype[0]))
514 warning_error_and_exit(wi, "Bond atom type names can't be single digits.", FARGS);
517 /* Hack to read old topologies */
518 if (gmx_strcasecmp(ptype, "D") == 0)
522 for (j = 0; (j < eptNR); j++)
524 if (gmx_strcasecmp(ptype, xl[j].entry) == 0)
531 auto message = gmx::formatString("Invalid particle type %s", ptype);
532 warning_error_and_exit(wi, message, FARGS);
539 for (int i = 0; i < MAXFORCEPARAM; i++)
541 forceParam[i] = c[i];
544 InteractionType interactionType({}, forceParam, "");
546 batype_nr = bondAtomType->addBondAtomType(symtab, btype);
548 if ((nr = at->atomTypeFromName(type)) != NOTSET)
550 auto message = gmx::formatString("Overriding atomtype %s", type);
551 warning(wi, message);
552 if ((nr = at->setType(nr, symtab, *atom, type, interactionType, batype_nr,
555 auto message = gmx::formatString("Replacing atomtype %s failed", type);
556 warning_error_and_exit(wi, message, FARGS);
559 else if ((at->addType(symtab, *atom, type, interactionType,
560 batype_nr, atomnr)) == NOTSET)
562 auto message = gmx::formatString("Adding atomtype %s failed", type);
563 warning_error_and_exit(wi, message, FARGS);
567 /* Add space in the non-bonded parameters matrix */
568 realloc_nb_params(at, nbparam, pair);
573 //! Return whether the contents of \c a and \c b are the same, considering also reversed order.
574 template <typename T>
575 static bool equalEitherForwardOrBackward(gmx::ArrayRef<const T> a, gmx::ArrayRef<const T> b)
577 return (std::equal(a.begin(), a.end(), b.begin()) ||
578 std::equal(a.begin(), a.end(), b.rbegin()));
581 static void push_bondtype(InteractionTypeParameters *bt,
582 const InteractionType &b,
590 int nrfp = NRFP(ftype);
592 /* If bAllowRepeat is TRUE, we allow multiple entries as long as they
593 are on directly _adjacent_ lines.
596 /* First check if our atomtypes are _identical_ (not reversed) to the previous
597 entry. If they are not identical we search for earlier duplicates. If they are
598 we can skip it, since we already searched for the first line
602 bool isContinuationOfBlock = false;
603 if (bAllowRepeat && nr > 1)
605 isContinuationOfBlock = true;
606 gmx::ArrayRef<const int> newParAtom = b.atoms();
607 gmx::ArrayRef<const int> sysParAtom = bt->interactionTypes[nr - 2].atoms();
608 for (int j = 0; j < nral; j++)
610 if (newParAtom[j] != sysParAtom[j])
612 isContinuationOfBlock = false;
617 /* Search for earlier duplicates if this entry was not a continuation
618 from the previous line.
620 bool addBondType = true;
621 bool haveWarned = false;
622 bool haveErrored = false;
623 for (int i = 0; (i < nr); i++)
625 gmx::ArrayRef<const int> bParams = b.atoms();
626 gmx::ArrayRef<const int> testParams = bt->interactionTypes[i].atoms();
627 GMX_RELEASE_ASSERT(bParams.size() == testParams.size(), "Number of atoms needs to be the same between parameters");
628 if (equalEitherForwardOrBackward(bParams, testParams))
630 GMX_ASSERT(nrfp <= MAXFORCEPARAM, "This is ensured in other places, but we need this assert to keep the clang analyzer happy");
631 const bool identicalParameters = std::equal(bt->interactionTypes[i].forceParam().begin(),
632 bt->interactionTypes[i].forceParam().begin() + nrfp, b.forceParam().begin());
634 if (!bAllowRepeat || identicalParameters)
639 if (!identicalParameters)
643 /* With dihedral type 9 we only allow for repeating
644 * of the same parameters with blocks with 1 entry.
645 * Allowing overriding is too complex to check.
647 if (!isContinuationOfBlock && !haveErrored)
649 warning_error(wi, "Encountered a second block of parameters for dihedral "
650 "type 9 for the same atoms, with either different parameters "
651 "and/or the first block has multiple lines. This is not supported.");
655 else if (!haveWarned)
657 auto message = gmx::formatString
658 ("Overriding %s parameters.%s",
659 interaction_function[ftype].longname,
661 "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive "
662 "lines are combined. Non-consective lines overwrite each other."
664 warning(wi, message);
666 fprintf(stderr, " old: ");
667 gmx::ArrayRef<const real> forceParam = bt->interactionTypes[i].forceParam();
668 for (int j = 0; j < nrfp; j++)
670 fprintf(stderr, " %g", forceParam[j]);
672 fprintf(stderr, " \n new: %s\n\n", line);
678 if (!identicalParameters && !bAllowRepeat)
680 /* Overwrite the parameters with the latest ones */
681 // TODO considering improving the following code by replacing with:
682 // std::copy(b->c, b->c + nrfp, bt->param[i].c);
683 gmx::ArrayRef<const real> forceParam = b.forceParam();
684 for (int j = 0; j < nrfp; j++)
686 bt->interactionTypes[i].setForceParameter(j, forceParam[j]);
694 /* fill the arrays up and down */
695 bt->interactionTypes.emplace_back(
696 InteractionType(b.atoms(), b.forceParam(), b.interactionTypeName()));
697 /* need to store force values because they might change below */
698 std::vector<real> forceParam(b.forceParam().begin(), b.forceParam().end());
700 /* The definitions of linear angles depend on the order of atoms,
701 * that means that for atoms i-j-k, with certain parameter a, the
702 * corresponding k-j-i angle will have parameter 1-a.
704 if (ftype == F_LINEAR_ANGLES)
706 forceParam[0] = 1- forceParam[0];
707 forceParam[2] = 1- forceParam[2];
709 std::vector<int> atoms;
710 gmx::ArrayRef<const int> oldAtoms = b.atoms();
711 for (auto oldAtom = oldAtoms.rbegin(); oldAtom != oldAtoms.rend(); oldAtom++)
713 atoms.emplace_back(*oldAtom);
715 bt->interactionTypes.emplace_back(InteractionType(atoms, forceParam, b.interactionTypeName()));
719 void push_bt(Directive d,
720 gmx::ArrayRef<InteractionTypeParameters> bt,
722 PreprocessingAtomTypes *at,
723 PreprocessingBondAtomType *bondAtomType,
727 const char *formal[MAXATOMLIST+1] = {
736 const char *formnl[MAXATOMLIST+1] = {
742 "%*s%*s%*s%*s%*s%*s",
743 "%*s%*s%*s%*s%*s%*s%*s"
745 const char *formlf = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
746 int i, ft, ftype, nn, nrfp, nrfpA;
748 char alc[MAXATOMLIST+1][20];
749 /* One force parameter more, so we can check if we read too many */
750 double c[MAXFORCEPARAM+1];
752 if ((bondAtomType && at) || (!bondAtomType && !at))
754 gmx_incons("You should pass either bondAtomType or at to push_bt");
757 /* Make format string (nral ints+functype) */
758 if ((nn = sscanf(line, formal[nral],
759 alc[0], alc[1], alc[2], alc[3], alc[4], alc[5])) != nral+1)
761 auto message = gmx::formatString("Not enough atomtypes (%d instead of %d)", nn-1, nral);
762 warning_error(wi, message);
766 ft = strtol(alc[nral], nullptr, 10);
767 ftype = ifunc_index(d, ft);
769 nrfpA = interaction_function[ftype].nrfpA;
770 strcpy(f1, formnl[nral]);
772 if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12]))
777 /* Copy the B-state from the A-state */
778 copy_B_from_A(ftype, c);
784 warning_error(wi, "Not enough parameters");
786 else if (nn > nrfpA && nn < nrfp)
788 warning_error(wi, "Too many parameters or not enough parameters for topology B");
792 warning_error(wi, "Too many parameters");
794 for (i = nn; (i < nrfp); i++)
800 std::vector<int> atoms;
801 std::array<real, MAXFORCEPARAM> forceParam;
802 for (int i = 0; (i < nral); i++)
805 if ((at != nullptr) && ((atomNumber = at->atomTypeFromName(alc[i])) == NOTSET))
807 auto message = gmx::formatString("Unknown atomtype %s\n", alc[i]);
808 warning_error_and_exit(wi, message, FARGS);
810 else if ((bondAtomType != nullptr) && ((atomNumber = bondAtomType->bondAtomTypeFromName(alc[i])) == NOTSET))
812 auto message = gmx::formatString("Unknown bond_atomtype %s\n", alc[i]);
813 warning_error_and_exit(wi, message, FARGS);
815 atoms.emplace_back(atomNumber);
817 for (int i = 0; (i < nrfp); i++)
819 forceParam[i] = c[i];
821 push_bondtype (&(bt[ftype]), InteractionType(atoms, forceParam), nral, ftype, FALSE, line, wi);
825 void push_dihedraltype(Directive d, gmx::ArrayRef<InteractionTypeParameters> bt,
826 PreprocessingBondAtomType *bondAtomType, char *line,
829 const char *formal[MAXATOMLIST+1] = {
838 const char *formnl[MAXATOMLIST+1] = {
844 "%*s%*s%*s%*s%*s%*s",
845 "%*s%*s%*s%*s%*s%*s%*s"
847 const char *formlf[MAXFORCEPARAM] = {
853 "%lf%lf%lf%lf%lf%lf",
854 "%lf%lf%lf%lf%lf%lf%lf",
855 "%lf%lf%lf%lf%lf%lf%lf%lf",
856 "%lf%lf%lf%lf%lf%lf%lf%lf%lf",
857 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
858 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
859 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
861 int i, ft, ftype, nn, nrfp, nrfpA, nral;
863 char alc[MAXATOMLIST+1][20];
864 double c[MAXFORCEPARAM];
867 /* This routine accepts dihedraltypes defined from either 2 or 4 atoms.
869 * We first check for 2 atoms with the 3th column being an integer
870 * defining the type. If this isn't the case, we try it with 4 atoms
871 * and the 5th column defining the dihedral type.
873 nn = sscanf(line, formal[4], alc[0], alc[1], alc[2], alc[3], alc[4]);
874 if (nn >= 3 && strlen(alc[2]) == 1 && isdigit(alc[2][0]))
877 ft = strtol(alc[nral], nullptr, 10);
878 /* Move atom types around a bit and use 'X' for wildcard atoms
879 * to create a 4-atom dihedral definition with arbitrary atoms in
882 if (alc[2][0] == '2')
884 /* improper - the two atomtypes are 1,4. Use wildcards for 2,3 */
885 strcpy(alc[3], alc[1]);
886 sprintf(alc[2], "X");
887 sprintf(alc[1], "X");
888 /* alc[0] stays put */
892 /* proper - the two atomtypes are 2,3. Use wildcards for 1,4 */
893 sprintf(alc[3], "X");
894 strcpy(alc[2], alc[1]);
895 strcpy(alc[1], alc[0]);
896 sprintf(alc[0], "X");
899 else if (nn == 5 && strlen(alc[4]) == 1 && isdigit(alc[4][0]))
902 ft = strtol(alc[nral], nullptr, 10);
906 auto message = gmx::formatString("Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn-1);
907 warning_error(wi, message);
913 /* Previously, we have always overwritten parameters if e.g. a torsion
914 with the same atomtypes occurs on multiple lines. However, CHARMM and
915 some other force fields specify multiple dihedrals over some bonds,
916 including cosines with multiplicity 6 and somethimes even higher.
917 Thus, they cannot be represented with Ryckaert-Bellemans terms.
918 To add support for these force fields, Dihedral type 9 is identical to
919 normal proper dihedrals, but repeated entries are allowed.
926 bAllowRepeat = FALSE;
930 ftype = ifunc_index(d, ft);
932 nrfpA = interaction_function[ftype].nrfpA;
934 strcpy(f1, formnl[nral]);
935 strcat(f1, formlf[nrfp-1]);
937 /* Check number of parameters given */
938 if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11]))
943 /* Copy the B-state from the A-state */
944 copy_B_from_A(ftype, c);
950 warning_error(wi, "Not enough parameters");
952 else if (nn > nrfpA && nn < nrfp)
954 warning_error(wi, "Too many parameters or not enough parameters for topology B");
958 warning_error(wi, "Too many parameters");
960 for (i = nn; (i < nrfp); i++)
967 std::vector<int> atoms;
968 std::array<real, MAXFORCEPARAM> forceParam;
969 for (int i = 0; (i < 4); i++)
971 if (!strcmp(alc[i], "X"))
973 atoms.emplace_back(-1);
978 if ((atomNumber = bondAtomType->bondAtomTypeFromName(alc[i])) == NOTSET)
980 auto message = gmx::formatString("Unknown bond_atomtype %s", alc[i]);
981 warning_error_and_exit(wi, message, FARGS);
983 atoms.emplace_back(atomNumber);
986 for (int i = 0; (i < nrfp); i++)
988 forceParam[i] = c[i];
990 /* Always use 4 atoms here, since we created two wildcard atoms
991 * if there wasn't of them 4 already.
993 push_bondtype (&(bt[ftype]), InteractionType(atoms, forceParam), 4, ftype, bAllowRepeat, line, wi);
997 void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes,
998 char *pline, int nb_funct,
1001 /* swap the atoms */
1002 const char *form3 = "%*s%*s%*s%lf%lf%lf";
1003 const char *form4 = "%*s%*s%*s%lf%lf%lf%lf";
1004 const char *form5 = "%*s%*s%*s%lf%lf%lf%lf%lf";
1005 char a0[80], a1[80];
1006 int i, f, n, ftype, nrfp;
1013 if (sscanf (pline, "%s%s%d", a0, a1, &f) != 3)
1019 ftype = ifunc_index(d, f);
1021 if (ftype != nb_funct)
1023 auto message = gmx::formatString("Trying to add %s while the default nonbond type is %s",
1024 interaction_function[ftype].longname,
1025 interaction_function[nb_funct].longname);
1026 warning_error(wi, message);
1030 /* Get the force parameters */
1032 if (ftype == F_LJ14)
1034 n = sscanf(pline, form4, &c[0], &c[1], &c[2], &c[3]);
1040 /* When the B topology parameters are not set,
1041 * copy them from topology A
1043 GMX_ASSERT(nrfp <= 4, "LJ-14 cannot have more than 4 parameters");
1044 for (i = n; i < nrfp; i++)
1049 else if (ftype == F_LJC14_Q)
1051 n = sscanf(pline, form5, &c[0], &c[1], &c[2], &c[3], &dum);
1054 incorrect_n_param(wi);
1060 if (sscanf(pline, form3, &c[0], &c[1], &dum) != 2)
1062 incorrect_n_param(wi);
1068 if (sscanf(pline, form4, &c[0], &c[1], &c[2], &dum) != 3)
1070 incorrect_n_param(wi);
1076 auto message = gmx::formatString("Number of force parameters for nonbonded interactions is %d", nrfp);
1077 warning_error_and_exit(wi, message, FARGS);
1079 for (i = 0; (i < nrfp); i++)
1084 /* Put the parameters in the matrix */
1085 if ((ai = atypes->atomTypeFromName(a0)) == NOTSET)
1087 auto message = gmx::formatString("Atomtype %s not found", a0);
1088 warning_error_and_exit(wi, message, FARGS);
1090 if ((aj = atypes->atomTypeFromName(a1)) == NOTSET)
1092 auto message = gmx::formatString("Atomtype %s not found", a1);
1093 warning_error_and_exit(wi, message, FARGS);
1095 nbp = &(nbt[std::max(ai, aj)][std::min(ai, aj)]);
1100 for (i = 0; i < nrfp; i++)
1102 bId = bId && (nbp->c[i] == cr[i]);
1106 auto message = gmx::formatString("Overriding non-bonded parameters,");
1107 warning(wi, message);
1108 fprintf(stderr, " old:");
1109 for (i = 0; i < nrfp; i++)
1111 fprintf(stderr, " %g", nbp->c[i]);
1113 fprintf(stderr, " new\n%s\n", pline);
1117 for (i = 0; i < nrfp; i++)
1124 push_cmaptype(Directive d,
1125 gmx::ArrayRef<InteractionTypeParameters> bt,
1127 PreprocessingAtomTypes *atomtypes,
1128 PreprocessingBondAtomType *bondAtomType,
1132 const char *formal = "%s%s%s%s%s%s%s%s%n";
1134 int ft, ftype, nn, nrfp, nrfpA, nrfpB;
1135 int start, nchar_consumed;
1136 int nxcmap, nycmap, ncmap, read_cmap, sl, nct;
1137 char s[20], alc[MAXATOMLIST+2][20];
1139 /* Keep the compiler happy */
1143 GMX_ASSERT(nral == 5, "CMAP requires 5 atoms per interaction");
1145 /* Here we can only check for < 8 */
1146 if ((nn = sscanf(line, formal, alc[0], alc[1], alc[2], alc[3], alc[4], alc[5], alc[6], alc[7], &nchar_consumed)) < nral+3)
1148 auto message = gmx::formatString("Incorrect number of atomtypes for cmap (%d instead of 5)", nn-1);
1149 warning_error(wi, message);
1152 start += nchar_consumed;
1154 ft = strtol(alc[nral], nullptr, 10);
1155 nxcmap = strtol(alc[nral+1], nullptr, 10);
1156 nycmap = strtol(alc[nral+2], nullptr, 10);
1158 /* Check for equal grid spacing in x and y dims */
1159 if (nxcmap != nycmap)
1161 auto message = gmx::formatString("Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap, nycmap);
1162 warning_error(wi, message);
1165 ncmap = nxcmap*nycmap;
1166 ftype = ifunc_index(d, ft);
1167 nrfpA = strtol(alc[6], nullptr, 10)*strtol(alc[6], nullptr, 10);
1168 nrfpB = strtol(alc[7], nullptr, 10)*strtol(alc[7], nullptr, 10);
1171 /* Read in CMAP parameters */
1173 for (int i = 0; i < ncmap; i++)
1175 while (isspace(*(line+start+sl)))
1179 nn = sscanf(line+start+sl, " %s ", s);
1181 bt[F_CMAP].cmap.emplace_back(strtod(s, nullptr));
1189 auto message = gmx::formatString("Error in reading cmap parameter for angle %s %s %s %s %s", alc[0], alc[1], alc[2], alc[3], alc[4]);
1190 warning_error(wi, message);
1195 /* Check do that we got the number of parameters we expected */
1196 if (read_cmap == nrfpA)
1198 for (int i = 0; i < ncmap; i++)
1200 bt[F_CMAP].cmap.emplace_back(bt[F_CMAP].cmap[i]);
1205 if (read_cmap < nrfpA)
1207 warning_error(wi, "Not enough cmap parameters");
1209 else if (read_cmap > nrfpA && read_cmap < nrfp)
1211 warning_error(wi, "Too many cmap parameters or not enough parameters for topology B");
1213 else if (read_cmap > nrfp)
1215 warning_error(wi, "Too many cmap parameters");
1220 /* Set grid spacing and the number of grids (we assume these numbers to be the same for all grids
1221 * so we can safely assign them each time
1223 bt[F_CMAP].cmakeGridSpacing = nxcmap; /* Or nycmap, they need to be equal */
1224 bt[F_CMAP].cmapAngles++; /* Since we are incrementing here, we need to subtract later, see (*****) */
1225 nct = (nral+1) * bt[F_CMAP].cmapAngles;
1227 std::vector<int> atoms;
1228 for (int i = 0; (i < nral); i++)
1231 if ((atomtypes != nullptr) && ((atomNumber = bondAtomType->bondAtomTypeFromName(alc[i])) == NOTSET))
1233 auto message = gmx::formatString("Unknown atomtype %s\n", alc[i]);
1234 warning_error(wi, message);
1236 else if ((bondAtomType != nullptr) && ((atomNumber = bondAtomType->bondAtomTypeFromName(alc[i])) == NOTSET))
1238 auto message = gmx::formatString("Unknown bond_atomtype %s\n", alc[i]);
1239 warning_error(wi, message);
1241 atoms.emplace_back(atomNumber);
1243 /* Assign a grid number to each cmap_type */
1244 GMX_RELEASE_ASSERT(bondAtomType != nullptr, "Need valid PreprocessingBondAtomType object");
1245 bt[F_CMAP].cmapAtomTypes.emplace_back(bondAtomType->bondAtomTypeFromName(alc[i]));
1248 /* Assign a type number to this cmap */
1249 bt[F_CMAP].cmapAtomTypes.emplace_back(bt[F_CMAP].cmapAngles-1); /* Since we inremented earlier, we need to subtrac here, to get the types right (****) */
1251 /* Check for the correct number of atoms (again) */
1252 if (bt[F_CMAP].nct() != nct)
1254 auto message = gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n", nct, bt[F_CMAP].cmapAngles);
1255 warning_error(wi, message);
1258 std::array<real, MAXFORCEPARAM> forceParam = {NOTSET};
1260 /* Push the bond to the bondlist */
1261 push_bondtype (&(bt[ftype]), InteractionType(atoms, forceParam), nral, ftype, FALSE, line, wi);
1265 static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr,
1267 int type, char *ctype, int ptype,
1269 char *resname, char *name, real m0, real q0,
1270 int typeB, char *ctypeB, real mB, real qB,
1273 int j, resind = 0, resnr;
1277 if (((nr == 0) && (atomnr != 1)) || (nr && (atomnr != at->nr+1)))
1279 auto message = gmx::formatString
1280 ("Atoms in the .top are not numbered consecutively from 1 (rather, "
1281 "atomnr = %d, while at->nr = %d)", atomnr, at->nr);
1282 warning_error_and_exit(wi, message, FARGS);
1285 j = strlen(resnumberic) - 1;
1286 if (isdigit(resnumberic[j]))
1292 ric = resnumberic[j];
1293 if (j == 0 || !isdigit(resnumberic[j-1]))
1295 auto message = gmx::formatString("Invalid residue number '%s' for atom %d",
1296 resnumberic, atomnr);
1297 warning_error_and_exit(wi, message, FARGS);
1300 resnr = strtol(resnumberic, nullptr, 10);
1304 resind = at->atom[nr-1].resind;
1306 if (nr == 0 || strcmp(resname, *at->resinfo[resind].name) != 0 ||
1307 resnr != at->resinfo[resind].nr ||
1308 ric != at->resinfo[resind].ic)
1318 at->nres = resind + 1;
1319 srenew(at->resinfo, at->nres);
1320 at->resinfo[resind].name = put_symtab(symtab, resname);
1321 at->resinfo[resind].nr = resnr;
1322 at->resinfo[resind].ic = ric;
1326 resind = at->atom[at->nr-1].resind;
1329 /* New atom instance
1330 * get new space for arrays
1332 srenew(at->atom, nr+1);
1333 srenew(at->atomname, nr+1);
1334 srenew(at->atomtype, nr+1);
1335 srenew(at->atomtypeB, nr+1);
1338 at->atom[nr].type = type;
1339 at->atom[nr].ptype = ptype;
1340 at->atom[nr].q = q0;
1341 at->atom[nr].m = m0;
1342 at->atom[nr].typeB = typeB;
1343 at->atom[nr].qB = qB;
1344 at->atom[nr].mB = mB;
1346 at->atom[nr].resind = resind;
1347 at->atom[nr].atomnumber = atomicnumber;
1348 at->atomname[nr] = put_symtab(symtab, name);
1349 at->atomtype[nr] = put_symtab(symtab, ctype);
1350 at->atomtypeB[nr] = put_symtab(symtab, ctypeB);
1354 static void push_cg(t_block *block, int *lastindex, int index, int a)
1356 if (((block->nr) && (*lastindex != index)) || (!block->nr))
1358 /* add a new block */
1360 srenew(block->index, block->nr+1);
1362 block->index[block->nr] = a + 1;
1366 void push_atom(t_symtab *symtab, t_block *cgs,
1367 t_atoms *at, PreprocessingAtomTypes *atypes, char *line, int *lastcg,
1371 int cgnumber, atomnr, type, typeB, nscan;
1372 char id[STRLEN], ctype[STRLEN], ctypeB[STRLEN],
1373 resnumberic[STRLEN], resname[STRLEN], name[STRLEN], check[STRLEN];
1374 double m, q, mb, qb;
1375 real m0, q0, mB, qB;
1377 /* Make a shortcut for writing in this molecule */
1380 /* Fixed parameters */
1381 if (sscanf(line, "%s%s%s%s%s%d",
1382 id, ctype, resnumberic, resname, name, &cgnumber) != 6)
1387 sscanf(id, "%d", &atomnr);
1388 if ((type = atypes->atomTypeFromName(ctype)) == NOTSET)
1390 auto message = gmx::formatString("Atomtype %s not found", ctype);
1391 warning_error_and_exit(wi, message, FARGS);
1393 ptype = atypes->atomParticleTypeFromAtomType(type);
1395 /* Set default from type */
1396 q0 = atypes->atomChargeFromAtomType(type);
1397 m0 = atypes->atomMassFromAtomType(type);
1402 /* Optional parameters */
1403 nscan = sscanf(line, "%*s%*s%*s%*s%*s%*s%lf%lf%s%lf%lf%s",
1404 &q, &m, ctypeB, &qb, &mb, check);
1406 /* Nasty switch that falls thru all the way down! */
1415 if ((typeB = atypes->atomTypeFromName(ctypeB)) == NOTSET)
1417 auto message = gmx::formatString("Atomtype %s not found", ctypeB);
1418 warning_error_and_exit(wi, message, FARGS);
1420 qB = atypes->atomChargeFromAtomType(typeB);
1421 mB = atypes->atomMassFromAtomType(typeB);
1430 warning_error(wi, "Too many parameters");
1438 push_cg(cgs, lastcg, cgnumber, nr);
1440 push_atom_now(symtab, at, atomnr, atypes->atomNumberFromAtomType(type),
1441 type, ctype, ptype, resnumberic,
1442 resname, name, m0, q0, typeB,
1443 typeB == type ? ctype : ctypeB, mB, qB, wi);
1446 void push_molt(t_symtab *symtab,
1447 std::vector<MoleculeInformation> *mol,
1454 if ((sscanf(line, "%s%d", type, &nrexcl)) != 2)
1456 warning_error(wi, "Expected a molecule type name and nrexcl");
1459 /* Test if this moleculetype overwrites another */
1460 const auto found = std::find_if(mol->begin(), mol->end(),
1461 [&type](const auto &m)
1462 { return strcmp(*(m.name), type) == 0; });
1463 if (found != mol->end())
1465 auto message = gmx::formatString("moleculetype %s is redefined", type);
1466 warning_error_and_exit(wi, message, FARGS);
1469 mol->emplace_back();
1470 mol->back().initMolInfo();
1472 /* Fill in the values */
1473 mol->back().name = put_symtab(symtab, type);
1474 mol->back().nrexcl = nrexcl;
1475 mol->back().excl_set = false;
1478 static bool findIfAllNBAtomsMatch(gmx::ArrayRef<const int> atomsFromParameterArray,
1479 gmx::ArrayRef<const int> atomsFromCurrentParameter,
1483 if (atomsFromParameterArray.size() != atomsFromCurrentParameter.size())
1489 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1491 if (at->atom[atomsFromCurrentParameter[i]].typeB != atomsFromParameterArray[i])
1500 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1502 if (at->atom[atomsFromCurrentParameter[i]].type != atomsFromParameterArray[i])
1511 static bool default_nb_params(int ftype, gmx::ArrayRef<InteractionTypeParameters> bt, t_atoms *at,
1512 InteractionType *p, int c_start, bool bB, bool bGenPairs)
1516 InteractionType *pi = nullptr;
1517 int nr = bt[ftype].size();
1518 int nral = NRAL(ftype);
1519 int nrfp = interaction_function[ftype].nrfpA;
1520 int nrfpB = interaction_function[ftype].nrfpB;
1522 if ((!bB && nrfp == 0) || (bB && nrfpB == 0))
1530 /* First test the generated-pair position to save
1531 * time when we have 1000*1000 entries for e.g. OPLS...
1533 ntype = static_cast<int>(std::sqrt(static_cast<double>(nr)));
1534 GMX_ASSERT(ntype * ntype == nr, "Number of pairs of generated non-bonded parameters should be a perfect square");
1537 ti = at->atom[p->ai()].typeB;
1538 tj = at->atom[p->aj()].typeB;
1542 ti = at->atom[p->ai()].type;
1543 tj = at->atom[p->aj()].type;
1545 pi = &(bt[ftype].interactionTypes[ntype*ti+tj]);
1546 if (pi->atoms().ssize() < nral)
1548 /* not initialized yet with atom names */
1553 bFound = ((ti == pi->ai()) && (tj == pi->aj()));
1557 gmx::ArrayRef<const int> paramAtoms = p->atoms();
1558 /* Search explicitly if we didnt find it */
1561 auto foundParameter = std::find_if(bt[ftype].interactionTypes.begin(),
1562 bt[ftype].interactionTypes.end(),
1563 [¶mAtoms, &at, &bB](const auto ¶m)
1564 { return findIfAllNBAtomsMatch(param.atoms(), paramAtoms, at, bB); });
1565 if (foundParameter != bt[ftype].interactionTypes.end())
1568 pi = &(*foundParameter);
1574 gmx::ArrayRef<const real> forceParam = pi->forceParam();
1577 if (nrfp+nrfpB > MAXFORCEPARAM)
1579 gmx_incons("Too many force parameters");
1581 for (int j = c_start; j < nrfpB; j++)
1583 p->setForceParameter(nrfp+j, forceParam[j]);
1588 for (int j = c_start; j < nrfp; j++)
1590 p->setForceParameter(j, forceParam[j]);
1596 for (int j = c_start; j < nrfp; j++)
1598 p->setForceParameter(j, 0.0);
1604 static bool default_cmap_params(gmx::ArrayRef<InteractionTypeParameters> bondtype,
1605 t_atoms *at, PreprocessingAtomTypes *atypes,
1606 InteractionType *p, bool bB,
1607 int *cmap_type, int *nparam_def,
1612 bool bFound = false;
1617 /* Match the current cmap angle against the list of cmap_types */
1618 for (int i = 0; i < bondtype[F_CMAP].nct() && !bFound; i += 6)
1627 (atypes->bondAtomTypeFromAtomType(at->atom[p->ai()].type) == bondtype[F_CMAP].cmapAtomTypes[i]) &&
1628 (atypes->bondAtomTypeFromAtomType(at->atom[p->aj()].type) == bondtype[F_CMAP].cmapAtomTypes[i+1]) &&
1629 (atypes->bondAtomTypeFromAtomType(at->atom[p->ak()].type) == bondtype[F_CMAP].cmapAtomTypes[i+2]) &&
1630 (atypes->bondAtomTypeFromAtomType(at->atom[p->al()].type) == bondtype[F_CMAP].cmapAtomTypes[i+3]) &&
1631 (atypes->bondAtomTypeFromAtomType(at->atom[p->am()].type) == bondtype[F_CMAP].cmapAtomTypes[i+4]))
1633 /* Found cmap torsion */
1635 ct = bondtype[F_CMAP].cmapAtomTypes[i+5];
1641 /* If we did not find a matching type for this cmap torsion */
1644 auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d",
1645 p->ai()+1, p->aj()+1, p->ak()+1, p->al()+1, p->am()+1);
1646 warning_error_and_exit(wi, message, FARGS);
1649 *nparam_def = nparam_found;
1655 /* Returns the number of exact atom type matches, i.e. non wild-card matches,
1656 * returns -1 when there are no matches at all.
1658 static int natom_match(const InteractionType &pi,
1659 int type_i, int type_j, int type_k, int type_l,
1660 const PreprocessingAtomTypes* atypes)
1662 if ((pi.ai() == -1 || atypes->bondAtomTypeFromAtomType(type_i) == pi.ai()) &&
1663 (pi.aj() == -1 || atypes->bondAtomTypeFromAtomType(type_j) == pi.aj()) &&
1664 (pi.ak() == -1 || atypes->bondAtomTypeFromAtomType(type_k) == pi.ak()) &&
1665 (pi.al() == -1 || atypes->bondAtomTypeFromAtomType(type_l) == pi.al()))
1668 (pi.ai() == -1 ? 0 : 1) +
1669 (pi.aj() == -1 ? 0 : 1) +
1670 (pi.ak() == -1 ? 0 : 1) +
1671 (pi.al() == -1 ? 0 : 1);
1679 static int findNumberOfDihedralAtomMatches(const InteractionType ¤tParamFromParameterArray,
1680 const InteractionType ¶meterToAdd,
1682 const PreprocessingAtomTypes *atypes,
1687 return natom_match(currentParamFromParameterArray,
1688 at->atom[parameterToAdd.ai()].typeB,
1689 at->atom[parameterToAdd.aj()].typeB,
1690 at->atom[parameterToAdd.ak()].typeB,
1691 at->atom[parameterToAdd.al()].typeB, atypes);
1695 return natom_match(currentParamFromParameterArray,
1696 at->atom[parameterToAdd.ai()].type,
1697 at->atom[parameterToAdd.aj()].type,
1698 at->atom[parameterToAdd.ak()].type,
1699 at->atom[parameterToAdd.al()].type, atypes);
1703 static bool findIfAllParameterAtomsMatch(gmx::ArrayRef<const int> atomsFromParameterArray,
1704 gmx::ArrayRef<const int> atomsFromCurrentParameter,
1706 const PreprocessingAtomTypes *atypes,
1709 if (atomsFromParameterArray.size() != atomsFromCurrentParameter.size())
1715 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1717 if (atypes->bondAtomTypeFromAtomType(
1718 at->atom[atomsFromCurrentParameter[i]].typeB) != atomsFromParameterArray[i])
1727 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1729 if (atypes->bondAtomTypeFromAtomType(
1730 at->atom[atomsFromCurrentParameter[i]].type) != atomsFromParameterArray[i])
1739 static std::vector<InteractionType>::iterator
1740 defaultInteractionTypeParameters(int ftype, gmx::ArrayRef<InteractionTypeParameters> bt,
1741 t_atoms *at, PreprocessingAtomTypes *atypes,
1742 const InteractionType &p, bool bB,
1746 int nrfpA = interaction_function[ftype].nrfpA;
1747 int nrfpB = interaction_function[ftype].nrfpB;
1749 if ((!bB && nrfpA == 0) || (bB && nrfpB == 0))
1751 return bt[ftype].interactionTypes.end();
1756 if (ftype == F_PDIHS || ftype == F_RBDIHS || ftype == F_IDIHS || ftype == F_PIDIHS)
1758 int nmatch_max = -1;
1760 /* For dihedrals we allow wildcards. We choose the first type
1761 * that has the most real matches, i.e. non-wildcard matches.
1763 auto prevPos = bt[ftype].interactionTypes.end();
1764 auto pos = bt[ftype].interactionTypes.begin();
1765 while (pos != bt[ftype].interactionTypes.end() && nmatch_max < 4)
1767 pos = std::find_if(bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(),
1768 [&p, &at, &atypes, &bB, &nmatch_max](const auto ¶m)
1769 { return (findNumberOfDihedralAtomMatches(param, p, at, atypes, bB) > nmatch_max); });
1770 if (pos != bt[ftype].interactionTypes.end())
1773 nmatch_max = findNumberOfDihedralAtomMatches(*pos, p, at, atypes, bB);
1777 if (prevPos != bt[ftype].interactionTypes.end())
1781 /* Find additional matches for this dihedral - necessary
1783 * The rule in that case is that additional matches
1784 * HAVE to be on adjacent lines!
1787 //Advance iterator (like std::advance) without incrementing past end (UB)
1788 const auto safeAdvance = [](auto &it, auto n, auto end) {
1789 it = end-it > n ? it+n : end;
1791 /* Continue from current iterator position */
1792 auto nextPos = prevPos;
1793 const auto endIter = bt[ftype].interactionTypes.end();
1794 safeAdvance(nextPos, 2, endIter);
1795 for (; nextPos < endIter && bSame; safeAdvance(nextPos, 2, endIter))
1797 bSame = (prevPos->ai() == nextPos->ai() && prevPos->aj() == nextPos->aj() && prevPos->ak() == nextPos->ak() && prevPos->al() == nextPos->al());
1802 /* nparam_found will be increased as long as the numbers match */
1805 *nparam_def = nparam_found;
1808 else /* Not a dihedral */
1810 gmx::ArrayRef<const int> atomParam = p.atoms();
1811 auto found = std::find_if(bt[ftype].interactionTypes.begin(),
1812 bt[ftype].interactionTypes.end(),
1813 [&atomParam, &at, &atypes, &bB](const auto ¶m)
1814 { return findIfAllParameterAtomsMatch(param.atoms(), atomParam, at, atypes, bB); });
1815 if (found != bt[ftype].interactionTypes.end())
1819 *nparam_def = nparam_found;
1826 void push_bond(Directive d, gmx::ArrayRef<InteractionTypeParameters> bondtype,
1827 gmx::ArrayRef<InteractionTypeParameters> bond,
1828 t_atoms *at, PreprocessingAtomTypes *atypes, char *line,
1829 bool bBonded, bool bGenPairs, real fudgeQQ,
1830 bool bZero, bool *bWarn_copy_A_B,
1833 const char *aaformat[MAXATOMLIST] = {
1841 const char *asformat[MAXATOMLIST] = {
1846 "%*s%*s%*s%*s%*s%*s",
1847 "%*s%*s%*s%*s%*s%*s%*s"
1849 const char *ccformat = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
1850 int nral, nral_fmt, nread, ftype;
1851 char format[STRLEN];
1852 /* One force parameter more, so we can check if we read too many */
1853 double cc[MAXFORCEPARAM+1];
1854 int aa[MAXATOMLIST+1];
1855 bool bFoundA = FALSE, bFoundB = FALSE, bDef, bSwapParity = FALSE;
1856 int nparam_defA, nparam_defB;
1858 nparam_defA = nparam_defB = 0;
1860 ftype = ifunc_index(d, 1);
1862 for (int j = 0; j < nral; j++)
1866 bDef = (NRFP(ftype) > 0);
1868 if (ftype == F_SETTLE)
1870 /* SETTLE acts on 3 atoms, but the topology format only specifies
1871 * the first atom (for historical reasons).
1880 nread = sscanf(line, aaformat[nral_fmt-1],
1881 &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]);
1883 if (ftype == F_SETTLE)
1890 if (nread < nral_fmt)
1895 else if (nread > nral_fmt)
1897 /* this is a hack to allow for virtual sites with swapped parity */
1898 bSwapParity = (aa[nral] < 0);
1901 aa[nral] = -aa[nral];
1903 ftype = ifunc_index(d, aa[nral]);
1912 auto message = gmx::formatString("Negative function types only allowed for %s and %s",
1913 interaction_function[F_VSITE3FAD].longname,
1914 interaction_function[F_VSITE3OUT].longname);
1915 warning_error_and_exit(wi, message, FARGS);
1921 /* Check for double atoms and atoms out of bounds */
1922 for (int i = 0; (i < nral); i++)
1924 if (aa[i] < 1 || aa[i] > at->nr)
1926 auto message = gmx::formatString
1927 ("Atom index (%d) in %s out of bounds (1-%d).\n"
1928 "This probably means that you have inserted topology section \"%s\"\n"
1929 "in a part belonging to a different molecule than you intended to.\n"
1930 "In that case move the \"%s\" section to the right molecule.",
1931 aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
1932 warning_error_and_exit(wi, message, FARGS);
1934 for (int j = i+1; (j < nral); j++)
1936 GMX_ASSERT(j < MAXATOMLIST + 1, "Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy");
1939 auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
1940 if (ftype == F_ANGRES)
1942 /* Since the angle restraints uses 2 pairs of atoms to
1943 * defines an angle between vectors, it can be useful
1944 * to use one atom twice, so we only issue a note here.
1946 warning_note(wi, message);
1950 warning_error(wi, message);
1956 /* default force parameters */
1957 std::vector<int> atoms;
1958 for (int j = 0; (j < nral); j++)
1960 atoms.emplace_back(aa[j]-1);
1962 /* need to have an empty but initialized param array for some reason */
1963 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
1965 /* Get force params for normal and free energy perturbation
1966 * studies, as determined by types!
1968 InteractionType param(atoms, forceParam, "");
1970 std::vector<InteractionType>::iterator foundAParameter = bondtype[ftype].interactionTypes.end();
1971 std::vector<InteractionType>::iterator foundBParameter = bondtype[ftype].interactionTypes.end();
1974 foundAParameter = defaultInteractionTypeParameters(ftype,
1981 if (foundAParameter != bondtype[ftype].interactionTypes.end())
1983 /* Copy the A-state and B-state default parameters. */
1984 GMX_ASSERT(NRFPA(ftype)+NRFPB(ftype) <= MAXFORCEPARAM, "Bonded interactions may have at most 12 parameters");
1985 gmx::ArrayRef<const real> defaultParam = foundAParameter->forceParam();
1986 for (int j = 0; (j < NRFPA(ftype)+NRFPB(ftype)); j++)
1988 param.setForceParameter(j, defaultParam[j]);
1992 else if (NRFPA(ftype) == 0)
1996 foundBParameter = defaultInteractionTypeParameters(ftype,
2003 if (foundBParameter != bondtype[ftype].interactionTypes.end())
2005 /* Copy only the B-state default parameters */
2006 gmx::ArrayRef<const real> defaultParam = foundBParameter->forceParam();
2007 for (int j = NRFPA(ftype); (j < NRFP(ftype)); j++)
2009 param.setForceParameter(j, defaultParam[j]);
2013 else if (NRFPB(ftype) == 0)
2018 else if (ftype == F_LJ14)
2020 bFoundA = default_nb_params(ftype, bondtype, at, ¶m, 0, FALSE, bGenPairs);
2021 bFoundB = default_nb_params(ftype, bondtype, at, ¶m, 0, TRUE, bGenPairs);
2023 else if (ftype == F_LJC14_Q)
2025 /* Fill in the A-state charges as default parameters */
2026 param.setForceParameter(0, fudgeQQ);
2027 param.setForceParameter(1, at->atom[param.ai()].q);
2028 param.setForceParameter(2, at->atom[param.aj()].q);
2029 /* The default LJ parameters are the standard 1-4 parameters */
2030 bFoundA = default_nb_params(F_LJ14, bondtype, at, ¶m, 3, FALSE, bGenPairs);
2033 else if (ftype == F_LJC_PAIRS_NB)
2035 /* Defaults are not supported here */
2041 gmx_incons("Unknown function type in push_bond");
2044 if (nread > nral_fmt)
2046 /* Manually specified parameters - in this case we discard multiple torsion info! */
2048 strcpy(format, asformat[nral_fmt-1]);
2049 strcat(format, ccformat);
2051 nread = sscanf(line, format, &cc[0], &cc[1], &cc[2], &cc[3], &cc[4], &cc[5],
2052 &cc[6], &cc[7], &cc[8], &cc[9], &cc[10], &cc[11], &cc[12]);
2054 if ((nread == NRFPA(ftype)) && (NRFPB(ftype) != 0))
2056 /* We only have to issue a warning if these atoms are perturbed! */
2058 gmx::ArrayRef<const int> paramAtoms = param.atoms();
2059 for (int j = 0; (j < nral); j++)
2061 bPert = bPert || PERTURBED(at->atom[paramAtoms[j]]);
2064 if (bPert && *bWarn_copy_A_B)
2066 auto message = gmx::formatString("Some parameters for bonded interaction involving "
2067 "perturbed atoms are specified explicitly in "
2068 "state A, but not B - copying A to B");
2069 warning(wi, message);
2070 *bWarn_copy_A_B = FALSE;
2073 /* If only the A parameters were specified, copy them to the B state */
2074 /* The B-state parameters correspond to the first nrfpB
2075 * A-state parameters.
2077 for (int j = 0; (j < NRFPB(ftype)); j++)
2079 cc[nread++] = cc[j];
2083 /* If nread was 0 or EOF, no parameters were read => use defaults.
2084 * If nread was nrfpA we copied above so nread=nrfp.
2085 * If nread was nrfp we are cool.
2086 * For F_LJC14_Q we allow supplying fudgeQQ only.
2087 * Anything else is an error!
2089 if ((nread != 0) && (nread != EOF) && (nread != NRFP(ftype)) &&
2090 !(ftype == F_LJC14_Q && nread == 1))
2092 auto message = gmx::formatString
2093 ("Incorrect number of parameters - found %d, expected %d "
2094 "or %d for %s (after the function type).",
2095 nread, NRFPA(ftype), NRFP(ftype), interaction_function[ftype].longname);
2096 warning_error_and_exit(wi, message, FARGS);
2099 for (int j = 0; (j < nread); j++)
2101 param.setForceParameter(j, cc[j]);
2103 /* Check whether we have to use the defaults */
2104 if (nread == NRFP(ftype))
2113 /* nread now holds the number of force parameters read! */
2118 /* When we have multiple terms it would be very dangerous to allow perturbations to a different atom type! */
2119 if (ftype == F_PDIHS)
2121 if ((nparam_defA != nparam_defB) || ((nparam_defA > 1 || nparam_defB > 1) && (foundAParameter != foundBParameter)))
2124 gmx::formatString("Cannot automatically perturb a torsion with multiple terms to different form.\n"
2125 "Please specify perturbed parameters manually for this torsion in your topology!");
2126 warning_error(wi, message);
2130 if (nread > 0 && nread < NRFPA(ftype))
2132 /* Issue an error, do not use defaults */
2133 auto message = gmx::formatString("Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype));
2134 warning_error(wi, message);
2137 if (nread == 0 || nread == EOF)
2141 if (interaction_function[ftype].flags & IF_VSITE)
2143 for (int j = 0; j < MAXFORCEPARAM; j++)
2145 param.setForceParameter(j, NOTSET);
2149 /* flag to swap parity of vsi te construction */
2150 param.setForceParameter(1, -1);
2157 fprintf(stderr, "NOTE: No default %s types, using zeroes\n",
2158 interaction_function[ftype].longname);
2162 auto message = gmx::formatString("No default %s types", interaction_function[ftype].longname);
2163 warning_error(wi, message);
2174 param.setForceParameter(0, 360 - param.c0());
2177 param.setForceParameter(2, -param.c2());
2184 /* We only have to issue a warning if these atoms are perturbed! */
2186 gmx::ArrayRef<const int> paramAtoms = param.atoms();
2187 for (int j = 0; (j < nral); j++)
2189 bPert = bPert || PERTURBED(at->atom[paramAtoms[j]]);
2194 auto message = gmx::formatString("No default %s types for perturbed atoms, "
2195 "using normal values", interaction_function[ftype].longname);
2196 warning(wi, message);
2202 gmx::ArrayRef<const real> paramValue = param.forceParam();
2203 if ((ftype == F_PDIHS || ftype == F_ANGRES || ftype == F_ANGRESZ)
2204 && paramValue[5] != paramValue[2])
2206 auto message = gmx::formatString("%s multiplicity can not be perturbed %f!=%f",
2207 interaction_function[ftype].longname,
2208 paramValue[2], paramValue[5]);
2209 warning_error_and_exit(wi, message, FARGS);
2212 if (IS_TABULATED(ftype) && param.c0() != param.c2())
2214 auto message = gmx::formatString("%s table number can not be perturbed %d!=%d",
2215 interaction_function[ftype].longname,
2216 gmx::roundToInt(param.c0()), gmx::roundToInt(param.c0()));
2217 warning_error_and_exit(wi, message, FARGS);
2220 /* Dont add R-B dihedrals where all parameters are zero (no interaction) */
2221 if (ftype == F_RBDIHS)
2225 for (int i = 0; i < NRFP(ftype); i++)
2227 if (paramValue[i] != 0.0)
2238 /* Put the values in the appropriate arrays */
2239 add_param_to_list (&bond[ftype], param);
2241 /* Push additional torsions from FF for ftype==9 if we have them.
2242 * We have already checked that the A/B states do not differ in this case,
2243 * so we do not have to double-check that again, or the vsite stuff.
2244 * In addition, those torsions cannot be automatically perturbed.
2246 if (bDef && ftype == F_PDIHS)
2248 for (int i = 1; i < nparam_defA; i++)
2250 /* Advance pointer! */
2251 foundAParameter += 2;
2252 gmx::ArrayRef<const real> forceParam = foundAParameter->forceParam();
2253 for (int j = 0; j < (NRFPA(ftype)+NRFPB(ftype)); j++)
2255 param.setForceParameter(j, forceParam[j]);
2257 /* And push the next term for this torsion */
2258 add_param_to_list (&bond[ftype], param);
2263 void push_cmap(Directive d, gmx::ArrayRef<InteractionTypeParameters> bondtype,
2264 gmx::ArrayRef<InteractionTypeParameters> bond,
2265 t_atoms *at, PreprocessingAtomTypes *atypes, char *line,
2268 const char *aaformat[MAXATOMLIST+1] =
2279 int ftype, nral, nread, ncmap_params;
2281 int aa[MAXATOMLIST+1];
2284 ftype = ifunc_index(d, 1);
2288 nread = sscanf(line, aaformat[nral-1],
2289 &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]);
2296 else if (nread == nral)
2298 ftype = ifunc_index(d, 1);
2301 /* Check for double atoms and atoms out of bounds */
2302 for (int i = 0; i < nral; i++)
2304 if (aa[i] < 1 || aa[i] > at->nr)
2306 auto message = gmx::formatString
2307 ("Atom index (%d) in %s out of bounds (1-%d).\n"
2308 "This probably means that you have inserted topology section \"%s\"\n"
2309 "in a part belonging to a different molecule than you intended to.\n"
2310 "In that case move the \"%s\" section to the right molecule.",
2311 aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
2312 warning_error_and_exit(wi, message, FARGS);
2315 for (int j = i+1; (j < nral); j++)
2319 auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
2320 warning_error(wi, message);
2325 /* default force parameters */
2326 std::vector<int> atoms;
2327 for (int j = 0; (j < nral); j++)
2329 atoms.emplace_back(aa[j]-1);
2331 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
2332 InteractionType param(atoms, forceParam, "");
2333 /* Get the cmap type for this cmap angle */
2334 bFound = default_cmap_params(bondtype, at, atypes, ¶m, FALSE, &cmap_type, &ncmap_params, wi);
2336 /* We want exactly one parameter (the cmap type in state A (currently no state B) back */
2337 if (bFound && ncmap_params == 1)
2339 /* Put the values in the appropriate arrays */
2340 param.setForceParameter(0, cmap_type);
2341 add_param_to_list(&bond[ftype], param);
2345 /* This is essentially the same check as in default_cmap_params() done one more time */
2346 auto message = gmx::formatString("Unable to assign a cmap type to torsion %d %d %d %d and %d\n",
2347 param.ai()+1, param.aj()+1, param.ak()+1, param.al()+1, param.am()+1);
2348 warning_error_and_exit(wi, message, FARGS);
2354 void push_vsitesn(Directive d, gmx::ArrayRef<InteractionTypeParameters> bond,
2355 t_atoms *at, char *line,
2359 int type, ftype, n, ret, nj, a;
2361 double *weight = nullptr, weight_tot;
2363 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
2365 ret = sscanf(ptr, "%d%n", &a, &n);
2369 auto message = gmx::formatString("Expected an atom index in section \"%s\"",
2371 warning_error_and_exit(wi, message, FARGS);
2374 sscanf(ptr, "%d%n", &type, &n);
2376 ftype = ifunc_index(d, type);
2377 int firstAtom = a - 1;
2383 ret = sscanf(ptr, "%d%n", &a, &n);
2390 srenew(weight, nj+20);
2399 /* Here we use the A-state mass as a parameter.
2400 * Note that the B-state mass has no influence.
2402 weight[nj] = at->atom[atc[nj]].m;
2406 ret = sscanf(ptr, "%lf%n", &(weight[nj]), &n);
2410 auto message = gmx::formatString
2411 ("No weight or negative weight found for vsiten "
2412 "constructing atom %d (atom index %d)",
2414 warning_error_and_exit(wi, message, FARGS);
2418 auto message = gmx::formatString("Unknown vsiten type %d", type);
2419 warning_error_and_exit(wi, message, FARGS);
2421 weight_tot += weight[nj];
2429 auto message = gmx::formatString("Expected more than one atom index in section \"%s\"",
2431 warning_error_and_exit(wi, message, FARGS);
2434 if (weight_tot == 0)
2436 warning_error_and_exit(wi, "The total mass of the construting atoms is zero", FARGS);
2439 for (int j = 0; j < nj; j++)
2441 std::vector<int> atoms = {firstAtom, atc[j]};
2443 forceParam[1] = weight[j]/weight_tot;
2444 /* Put the values in the appropriate arrays */
2445 add_param_to_list (&bond[ftype], InteractionType(atoms, forceParam));
2452 void push_mol(gmx::ArrayRef<MoleculeInformation> mols, char *pline, int *whichmol,
2458 if (sscanf(pline, "%s%d", type, nrcopies) != 2)
2464 /* Search moleculename.
2465 * Here we originally only did case insensitive matching. But because
2466 * some PDB files can have many chains and use case to generate more
2467 * chain-identifiers, which in turn end up in our moleculetype name,
2468 * we added support for case-sensitivity.
2475 for (const auto &mol : mols)
2477 if (strcmp(type, *(mol.name)) == 0)
2482 if (gmx_strcasecmp(type, *(mol.name)) == 0)
2492 // select the case sensitive match
2493 *whichmol = matchcs;
2497 // avoid matching case-insensitive when we have multiple matches
2500 auto message = gmx::formatString
2501 ("For moleculetype '%s' in [ system ] %d case insensitive "
2502 "matches, but %d case sensitive matches were found. Check "
2503 "the case of the characters in the moleculetypes.",
2505 warning_error_and_exit(wi, message, FARGS);
2509 // select the unique case insensitive match
2510 *whichmol = matchci;
2514 auto message = gmx::formatString("No such moleculetype %s", type);
2515 warning_error_and_exit(wi, message, FARGS);
2520 void push_excl(char *line, gmx::ArrayRef<gmx::ExclusionBlock> b2, warninp *wi)
2524 char base[STRLEN], format[STRLEN];
2526 if (sscanf(line, "%d", &i) == 0)
2531 if ((1 <= i) && (i <= b2.ssize()))
2539 strcpy(base, "%*d");
2542 strcpy(format, base);
2543 strcat(format, "%d");
2544 n = sscanf(line, format, &j);
2547 if ((1 <= j) && (j <= b2.ssize()))
2550 b2[i].atomNumber.push_back(j);
2551 /* also add the reverse exclusion! */
2552 b2[j].atomNumber.push_back(i);
2553 strcat(base, "%*d");
2557 auto message = gmx::formatString("Invalid Atomnr j: %d, b2->nr: %zu\n", j, b2.size());
2558 warning_error_and_exit(wi, message, FARGS);
2565 int add_atomtype_decoupled(t_symtab *symtab, PreprocessingAtomTypes *at,
2566 t_nbparam ***nbparam, t_nbparam ***pair)
2571 /* Define an atom type with all parameters set to zero (no interactions) */
2574 /* Type for decoupled atoms could be anything,
2575 * this should be changed automatically later when required.
2577 atom.ptype = eptAtom;
2579 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
2580 nr = at->addType(symtab, atom, "decoupled", InteractionType({}, forceParam, ""), -1, 0);
2582 /* Add space in the non-bonded parameters matrix */
2583 realloc_nb_params(at, nbparam, pair);
2588 static void convert_pairs_to_pairsQ(gmx::ArrayRef<InteractionTypeParameters> plist,
2589 real fudgeQQ, t_atoms *atoms)
2591 /* Add the pair list to the pairQ list */
2592 std::vector<InteractionType> paramnew;
2594 gmx::ArrayRef<const InteractionType> paramp1 = plist[F_LJ14].interactionTypes;
2595 gmx::ArrayRef<const InteractionType> paramp2 = plist[F_LJC14_Q].interactionTypes;
2597 /* Fill in the new F_LJC14_Q array with the old one. NOTE:
2598 it may be possible to just ADD the converted F_LJ14 array
2599 to the old F_LJC14_Q array, but since we have to create
2600 a new sized memory structure, better just to deep copy it all.
2604 for (const auto ¶m : paramp2)
2606 paramnew.emplace_back(param);
2609 for (const auto ¶m : paramp1)
2611 std::vector<real> forceParam = {
2612 fudgeQQ, atoms->atom[param.ai()].q, atoms->atom[param.aj()].q,
2613 param.c0(), param.c1()
2615 paramnew.emplace_back(InteractionType(param.atoms(), forceParam, ""));
2618 /* now assign the new data to the F_LJC14_Q structure */
2619 plist[F_LJC14_Q].interactionTypes = paramnew;
2621 /* Empty the LJ14 pairlist */
2622 plist[F_LJ14].interactionTypes.clear();
2625 static void generate_LJCpairsNB(MoleculeInformation *mol, int nb_funct, InteractionTypeParameters *nbp, warninp *wi)
2633 atom = mol->atoms.atom;
2635 ntype = static_cast<int>(std::sqrt(static_cast<double>(nbp->size())));
2636 GMX_ASSERT(ntype * ntype == gmx::ssize(*nbp), "Number of pairs of generated non-bonded parameters should be a perfect square");
2638 /* Add a pair interaction for all non-excluded atom pairs */
2640 for (int i = 0; i < n; i++)
2642 for (int j = i+1; j < n; j++)
2645 for (int k = excl->index[i]; k < excl->index[i+1]; k++)
2647 if (excl->a[k] == j)
2654 if (nb_funct != F_LJ)
2656 auto message = gmx::formatString
2657 ("Can only generate non-bonded pair interactions "
2658 "for Van der Waals type Lennard-Jones");
2659 warning_error_and_exit(wi, message, FARGS);
2661 std::vector<int> atoms = {i, j};
2662 std::vector<real> forceParam = {
2665 nbp->interactionTypes[ntype*atom[i].type+atom[j].type].c0(),
2666 nbp->interactionTypes[ntype*atom[i].type+atom[j].type].c1()
2668 add_param_to_list(&mol->plist[F_LJC_PAIRS_NB], InteractionType(atoms, forceParam));
2674 static void set_excl_all(t_blocka *excl)
2678 /* Get rid of the current exclusions and exclude all atom pairs */
2680 excl->nra = nat*nat;
2681 srenew(excl->a, excl->nra);
2683 for (i = 0; i < nat; i++)
2686 for (j = 0; j < nat; j++)
2691 excl->index[nat] = k;
2694 static void decouple_atoms(t_atoms *atoms, int atomtype_decouple,
2695 int couple_lam0, int couple_lam1,
2696 const char *mol_name, warninp *wi)
2700 for (i = 0; i < atoms->nr; i++)
2704 atom = &atoms->atom[i];
2706 if (atom->qB != atom->q || atom->typeB != atom->type)
2708 auto message = gmx::formatString
2709 ("Atom %d in molecule type '%s' has different A and B state "
2710 "charges and/or atom types set in the topology file as well "
2711 "as through the mdp option '%s'. You can not use both "
2712 "these methods simultaneously.",
2713 i + 1, mol_name, "couple-moltype");
2714 warning_error_and_exit(wi, message, FARGS);
2717 if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamVDW)
2721 if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamQ)
2723 atom->type = atomtype_decouple;
2725 if (couple_lam1 == ecouplamNONE || couple_lam1 == ecouplamVDW)
2729 if (couple_lam1 == ecouplamNONE || couple_lam1 == ecouplamQ)
2731 atom->typeB = atomtype_decouple;
2736 void convert_moltype_couple(MoleculeInformation *mol, int atomtype_decouple, real fudgeQQ,
2737 int couple_lam0, int couple_lam1,
2738 bool bCoupleIntra, int nb_funct, InteractionTypeParameters *nbp,
2741 convert_pairs_to_pairsQ(mol->plist, fudgeQQ, &mol->atoms);
2744 generate_LJCpairsNB(mol, nb_funct, nbp, wi);
2745 set_excl_all(&mol->excls);
2747 decouple_atoms(&mol->atoms, atomtype_decouple, couple_lam0, couple_lam1,