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, gpp_bond_atomtype *bat,
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 if ((batype_nr = get_bond_atomtype_type(btype, bat)) == NOTSET)
548 add_bond_atomtype(bat, symtab, btype);
550 batype_nr = get_bond_atomtype_type(btype, bat);
552 if ((nr = at->atomTypeFromName(type)) != NOTSET)
554 auto message = gmx::formatString("Overriding atomtype %s", type);
555 warning(wi, message);
556 if ((nr = at->setType(nr, symtab, *atom, type, interactionType, batype_nr,
559 auto message = gmx::formatString("Replacing atomtype %s failed", type);
560 warning_error_and_exit(wi, message, FARGS);
563 else if ((at->addType(symtab, *atom, type, interactionType,
564 batype_nr, atomnr)) == NOTSET)
566 auto message = gmx::formatString("Adding atomtype %s failed", type);
567 warning_error_and_exit(wi, message, FARGS);
571 /* Add space in the non-bonded parameters matrix */
572 realloc_nb_params(at, nbparam, pair);
577 //! Return whether the contents of \c a and \c b are the same, considering also reversed order.
578 template <typename T>
579 static bool equalEitherForwardOrBackward(gmx::ArrayRef<const T> a, gmx::ArrayRef<const T> b)
581 return (std::equal(a.begin(), a.end(), b.begin()) ||
582 std::equal(a.begin(), a.end(), b.rbegin()));
585 static void push_bondtype(InteractionTypeParameters *bt,
586 const InteractionType &b,
594 int nrfp = NRFP(ftype);
596 /* If bAllowRepeat is TRUE, we allow multiple entries as long as they
597 are on directly _adjacent_ lines.
600 /* First check if our atomtypes are _identical_ (not reversed) to the previous
601 entry. If they are not identical we search for earlier duplicates. If they are
602 we can skip it, since we already searched for the first line
606 bool isContinuationOfBlock = false;
607 if (bAllowRepeat && nr > 1)
609 isContinuationOfBlock = true;
610 gmx::ArrayRef<const int> newParAtom = b.atoms();
611 gmx::ArrayRef<const int> sysParAtom = bt->interactionTypes[nr - 2].atoms();
612 for (int j = 0; j < nral; j++)
614 if (newParAtom[j] != sysParAtom[j])
616 isContinuationOfBlock = false;
621 /* Search for earlier duplicates if this entry was not a continuation
622 from the previous line.
624 bool addBondType = true;
625 bool haveWarned = false;
626 bool haveErrored = false;
627 for (int i = 0; (i < nr); i++)
629 gmx::ArrayRef<const int> bParams = b.atoms();
630 gmx::ArrayRef<const int> testParams = bt->interactionTypes[i].atoms();
631 GMX_RELEASE_ASSERT(bParams.size() == testParams.size(), "Number of atoms needs to be the same between parameters");
632 if (equalEitherForwardOrBackward(bParams, testParams))
634 GMX_ASSERT(nrfp <= MAXFORCEPARAM, "This is ensured in other places, but we need this assert to keep the clang analyzer happy");
635 const bool identicalParameters = std::equal(bt->interactionTypes[i].forceParam().begin(),
636 bt->interactionTypes[i].forceParam().begin() + nrfp, b.forceParam().begin());
638 if (!bAllowRepeat || identicalParameters)
643 if (!identicalParameters)
647 /* With dihedral type 9 we only allow for repeating
648 * of the same parameters with blocks with 1 entry.
649 * Allowing overriding is too complex to check.
651 if (!isContinuationOfBlock && !haveErrored)
653 warning_error(wi, "Encountered a second block of parameters for dihedral "
654 "type 9 for the same atoms, with either different parameters "
655 "and/or the first block has multiple lines. This is not supported.");
659 else if (!haveWarned)
661 auto message = gmx::formatString
662 ("Overriding %s parameters.%s",
663 interaction_function[ftype].longname,
665 "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive "
666 "lines are combined. Non-consective lines overwrite each other."
668 warning(wi, message);
670 fprintf(stderr, " old: ");
671 gmx::ArrayRef<const real> forceParam = bt->interactionTypes[i].forceParam();
672 for (int j = 0; j < nrfp; j++)
674 fprintf(stderr, " %g", forceParam[j]);
676 fprintf(stderr, " \n new: %s\n\n", line);
682 if (!identicalParameters && !bAllowRepeat)
684 /* Overwrite the parameters with the latest ones */
685 // TODO considering improving the following code by replacing with:
686 // std::copy(b->c, b->c + nrfp, bt->param[i].c);
687 gmx::ArrayRef<const real> forceParam = b.forceParam();
688 for (int j = 0; j < nrfp; j++)
690 bt->interactionTypes[i].setForceParameter(j, forceParam[j]);
698 /* fill the arrays up and down */
699 bt->interactionTypes.emplace_back(
700 InteractionType(b.atoms(), b.forceParam(), b.interactionTypeName()));
701 /* need to store force values because they might change below */
702 std::vector<real> forceParam(b.forceParam().begin(), b.forceParam().end());
704 /* The definitions of linear angles depend on the order of atoms,
705 * that means that for atoms i-j-k, with certain parameter a, the
706 * corresponding k-j-i angle will have parameter 1-a.
708 if (ftype == F_LINEAR_ANGLES)
710 forceParam[0] = 1- forceParam[0];
711 forceParam[2] = 1- forceParam[2];
713 std::vector<int> atoms;
714 gmx::ArrayRef<const int> oldAtoms = b.atoms();
715 for (auto oldAtom = oldAtoms.rbegin(); oldAtom != oldAtoms.rend(); oldAtom++)
717 atoms.emplace_back(*oldAtom);
719 bt->interactionTypes.emplace_back(InteractionType(atoms, forceParam, b.interactionTypeName()));
723 void push_bt(Directive d,
724 gmx::ArrayRef<InteractionTypeParameters> bt,
726 PreprocessingAtomTypes *at,
727 gpp_bond_atomtype *bat,
731 const char *formal[MAXATOMLIST+1] = {
740 const char *formnl[MAXATOMLIST+1] = {
746 "%*s%*s%*s%*s%*s%*s",
747 "%*s%*s%*s%*s%*s%*s%*s"
749 const char *formlf = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
750 int i, ft, ftype, nn, nrfp, nrfpA;
752 char alc[MAXATOMLIST+1][20];
753 /* One force parameter more, so we can check if we read too many */
754 double c[MAXFORCEPARAM+1];
756 if ((bat && at) || (!bat && !at))
758 gmx_incons("You should pass either bat or at to push_bt");
761 /* Make format string (nral ints+functype) */
762 if ((nn = sscanf(line, formal[nral],
763 alc[0], alc[1], alc[2], alc[3], alc[4], alc[5])) != nral+1)
765 auto message = gmx::formatString("Not enough atomtypes (%d instead of %d)", nn-1, nral);
766 warning_error(wi, message);
770 ft = strtol(alc[nral], nullptr, 10);
771 ftype = ifunc_index(d, ft);
773 nrfpA = interaction_function[ftype].nrfpA;
774 strcpy(f1, formnl[nral]);
776 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]))
781 /* Copy the B-state from the A-state */
782 copy_B_from_A(ftype, c);
788 warning_error(wi, "Not enough parameters");
790 else if (nn > nrfpA && nn < nrfp)
792 warning_error(wi, "Too many parameters or not enough parameters for topology B");
796 warning_error(wi, "Too many parameters");
798 for (i = nn; (i < nrfp); i++)
804 std::vector<int> atoms;
805 std::array<real, MAXFORCEPARAM> forceParam;
806 for (int i = 0; (i < nral); i++)
809 if ((at != nullptr) && ((atomNumber = at->atomTypeFromName(alc[i])) == NOTSET))
811 auto message = gmx::formatString("Unknown atomtype %s\n", alc[i]);
812 warning_error_and_exit(wi, message, FARGS);
814 else if (bat && ((atomNumber = get_bond_atomtype_type(alc[i], bat)) == NOTSET))
816 auto message = gmx::formatString("Unknown bond_atomtype %s\n", alc[i]);
817 warning_error_and_exit(wi, message, FARGS);
819 atoms.emplace_back(atomNumber);
821 for (int i = 0; (i < nrfp); i++)
823 forceParam[i] = c[i];
825 push_bondtype (&(bt[ftype]), InteractionType(atoms, forceParam), nral, ftype, FALSE, line, wi);
829 void push_dihedraltype(Directive d, gmx::ArrayRef<InteractionTypeParameters> bt,
830 gpp_bond_atomtype *bat, char *line,
833 const char *formal[MAXATOMLIST+1] = {
842 const char *formnl[MAXATOMLIST+1] = {
848 "%*s%*s%*s%*s%*s%*s",
849 "%*s%*s%*s%*s%*s%*s%*s"
851 const char *formlf[MAXFORCEPARAM] = {
857 "%lf%lf%lf%lf%lf%lf",
858 "%lf%lf%lf%lf%lf%lf%lf",
859 "%lf%lf%lf%lf%lf%lf%lf%lf",
860 "%lf%lf%lf%lf%lf%lf%lf%lf%lf",
861 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
862 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
863 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
865 int i, ft, ftype, nn, nrfp, nrfpA, nral;
867 char alc[MAXATOMLIST+1][20];
868 double c[MAXFORCEPARAM];
871 /* This routine accepts dihedraltypes defined from either 2 or 4 atoms.
873 * We first check for 2 atoms with the 3th column being an integer
874 * defining the type. If this isn't the case, we try it with 4 atoms
875 * and the 5th column defining the dihedral type.
877 nn = sscanf(line, formal[4], alc[0], alc[1], alc[2], alc[3], alc[4]);
878 if (nn >= 3 && strlen(alc[2]) == 1 && isdigit(alc[2][0]))
881 ft = strtol(alc[nral], nullptr, 10);
882 /* Move atom types around a bit and use 'X' for wildcard atoms
883 * to create a 4-atom dihedral definition with arbitrary atoms in
886 if (alc[2][0] == '2')
888 /* improper - the two atomtypes are 1,4. Use wildcards for 2,3 */
889 strcpy(alc[3], alc[1]);
890 sprintf(alc[2], "X");
891 sprintf(alc[1], "X");
892 /* alc[0] stays put */
896 /* proper - the two atomtypes are 2,3. Use wildcards for 1,4 */
897 sprintf(alc[3], "X");
898 strcpy(alc[2], alc[1]);
899 strcpy(alc[1], alc[0]);
900 sprintf(alc[0], "X");
903 else if (nn == 5 && strlen(alc[4]) == 1 && isdigit(alc[4][0]))
906 ft = strtol(alc[nral], nullptr, 10);
910 auto message = gmx::formatString("Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn-1);
911 warning_error(wi, message);
917 /* Previously, we have always overwritten parameters if e.g. a torsion
918 with the same atomtypes occurs on multiple lines. However, CHARMM and
919 some other force fields specify multiple dihedrals over some bonds,
920 including cosines with multiplicity 6 and somethimes even higher.
921 Thus, they cannot be represented with Ryckaert-Bellemans terms.
922 To add support for these force fields, Dihedral type 9 is identical to
923 normal proper dihedrals, but repeated entries are allowed.
930 bAllowRepeat = FALSE;
934 ftype = ifunc_index(d, ft);
936 nrfpA = interaction_function[ftype].nrfpA;
938 strcpy(f1, formnl[nral]);
939 strcat(f1, formlf[nrfp-1]);
941 /* Check number of parameters given */
942 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]))
947 /* Copy the B-state from the A-state */
948 copy_B_from_A(ftype, c);
954 warning_error(wi, "Not enough parameters");
956 else if (nn > nrfpA && nn < nrfp)
958 warning_error(wi, "Too many parameters or not enough parameters for topology B");
962 warning_error(wi, "Too many parameters");
964 for (i = nn; (i < nrfp); i++)
971 std::vector<int> atoms;
972 std::array<real, MAXFORCEPARAM> forceParam;
973 for (int i = 0; (i < 4); i++)
975 if (!strcmp(alc[i], "X"))
977 atoms.emplace_back(-1);
982 if ((atomNumber = get_bond_atomtype_type(alc[i], bat)) == NOTSET)
984 auto message = gmx::formatString("Unknown bond_atomtype %s", alc[i]);
985 warning_error_and_exit(wi, message, FARGS);
987 atoms.emplace_back(atomNumber);
990 for (int i = 0; (i < nrfp); i++)
992 forceParam[i] = c[i];
994 /* Always use 4 atoms here, since we created two wildcard atoms
995 * if there wasn't of them 4 already.
997 push_bondtype (&(bt[ftype]), InteractionType(atoms, forceParam), 4, ftype, bAllowRepeat, line, wi);
1001 void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes,
1002 char *pline, int nb_funct,
1005 /* swap the atoms */
1006 const char *form3 = "%*s%*s%*s%lf%lf%lf";
1007 const char *form4 = "%*s%*s%*s%lf%lf%lf%lf";
1008 const char *form5 = "%*s%*s%*s%lf%lf%lf%lf%lf";
1009 char a0[80], a1[80];
1010 int i, f, n, ftype, nrfp;
1017 if (sscanf (pline, "%s%s%d", a0, a1, &f) != 3)
1023 ftype = ifunc_index(d, f);
1025 if (ftype != nb_funct)
1027 auto message = gmx::formatString("Trying to add %s while the default nonbond type is %s",
1028 interaction_function[ftype].longname,
1029 interaction_function[nb_funct].longname);
1030 warning_error(wi, message);
1034 /* Get the force parameters */
1036 if (ftype == F_LJ14)
1038 n = sscanf(pline, form4, &c[0], &c[1], &c[2], &c[3]);
1044 /* When the B topology parameters are not set,
1045 * copy them from topology A
1047 GMX_ASSERT(nrfp <= 4, "LJ-14 cannot have more than 4 parameters");
1048 for (i = n; i < nrfp; i++)
1053 else if (ftype == F_LJC14_Q)
1055 n = sscanf(pline, form5, &c[0], &c[1], &c[2], &c[3], &dum);
1058 incorrect_n_param(wi);
1064 if (sscanf(pline, form3, &c[0], &c[1], &dum) != 2)
1066 incorrect_n_param(wi);
1072 if (sscanf(pline, form4, &c[0], &c[1], &c[2], &dum) != 3)
1074 incorrect_n_param(wi);
1080 auto message = gmx::formatString("Number of force parameters for nonbonded interactions is %d", nrfp);
1081 warning_error_and_exit(wi, message, FARGS);
1083 for (i = 0; (i < nrfp); i++)
1088 /* Put the parameters in the matrix */
1089 if ((ai = atypes->atomTypeFromName(a0)) == NOTSET)
1091 auto message = gmx::formatString("Atomtype %s not found", a0);
1092 warning_error_and_exit(wi, message, FARGS);
1094 if ((aj = atypes->atomTypeFromName(a1)) == NOTSET)
1096 auto message = gmx::formatString("Atomtype %s not found", a1);
1097 warning_error_and_exit(wi, message, FARGS);
1099 nbp = &(nbt[std::max(ai, aj)][std::min(ai, aj)]);
1104 for (i = 0; i < nrfp; i++)
1106 bId = bId && (nbp->c[i] == cr[i]);
1110 auto message = gmx::formatString("Overriding non-bonded parameters,");
1111 warning(wi, message);
1112 fprintf(stderr, " old:");
1113 for (i = 0; i < nrfp; i++)
1115 fprintf(stderr, " %g", nbp->c[i]);
1117 fprintf(stderr, " new\n%s\n", pline);
1121 for (i = 0; i < nrfp; i++)
1128 push_cmaptype(Directive d,
1129 gmx::ArrayRef<InteractionTypeParameters> bt,
1131 PreprocessingAtomTypes *at,
1132 gpp_bond_atomtype *bat,
1136 const char *formal = "%s%s%s%s%s%s%s%s%n";
1138 int ft, ftype, nn, nrfp, nrfpA, nrfpB;
1139 int start, nchar_consumed;
1140 int nxcmap, nycmap, ncmap, read_cmap, sl, nct;
1141 char s[20], alc[MAXATOMLIST+2][20];
1143 /* Keep the compiler happy */
1147 GMX_ASSERT(nral == 5, "CMAP requires 5 atoms per interaction");
1149 /* Here we can only check for < 8 */
1150 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)
1152 auto message = gmx::formatString("Incorrect number of atomtypes for cmap (%d instead of 5)", nn-1);
1153 warning_error(wi, message);
1156 start += nchar_consumed;
1158 ft = strtol(alc[nral], nullptr, 10);
1159 nxcmap = strtol(alc[nral+1], nullptr, 10);
1160 nycmap = strtol(alc[nral+2], nullptr, 10);
1162 /* Check for equal grid spacing in x and y dims */
1163 if (nxcmap != nycmap)
1165 auto message = gmx::formatString("Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap, nycmap);
1166 warning_error(wi, message);
1169 ncmap = nxcmap*nycmap;
1170 ftype = ifunc_index(d, ft);
1171 nrfpA = strtol(alc[6], nullptr, 10)*strtol(alc[6], nullptr, 10);
1172 nrfpB = strtol(alc[7], nullptr, 10)*strtol(alc[7], nullptr, 10);
1175 /* Read in CMAP parameters */
1177 for (int i = 0; i < ncmap; i++)
1179 while (isspace(*(line+start+sl)))
1183 nn = sscanf(line+start+sl, " %s ", s);
1185 bt[F_CMAP].cmap.emplace_back(strtod(s, nullptr));
1193 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]);
1194 warning_error(wi, message);
1199 /* Check do that we got the number of parameters we expected */
1200 if (read_cmap == nrfpA)
1202 for (int i = 0; i < ncmap; i++)
1204 bt[F_CMAP].cmap.emplace_back(bt[F_CMAP].cmap[i]);
1209 if (read_cmap < nrfpA)
1211 warning_error(wi, "Not enough cmap parameters");
1213 else if (read_cmap > nrfpA && read_cmap < nrfp)
1215 warning_error(wi, "Too many cmap parameters or not enough parameters for topology B");
1217 else if (read_cmap > nrfp)
1219 warning_error(wi, "Too many cmap parameters");
1224 /* Set grid spacing and the number of grids (we assume these numbers to be the same for all grids
1225 * so we can safely assign them each time
1227 bt[F_CMAP].cmakeGridSpacing = nxcmap; /* Or nycmap, they need to be equal */
1228 bt[F_CMAP].cmapAngles++; /* Since we are incrementing here, we need to subtract later, see (*****) */
1229 nct = (nral+1) * bt[F_CMAP].cmapAngles;
1231 std::vector<int> atoms;
1232 for (int i = 0; (i < nral); i++)
1235 if (at && ((atomNumber = get_bond_atomtype_type(alc[i], bat)) == NOTSET))
1237 auto message = gmx::formatString("Unknown atomtype %s\n", alc[i]);
1238 warning_error(wi, message);
1240 else if (bat && ((atomNumber = get_bond_atomtype_type(alc[i], bat)) == NOTSET))
1242 auto message = gmx::formatString("Unknown bond_atomtype %s\n", alc[i]);
1243 warning_error(wi, message);
1245 atoms.emplace_back(atomNumber);
1247 /* Assign a grid number to each cmap_type */
1248 bt[F_CMAP].cmapAtomTypes.emplace_back(get_bond_atomtype_type(alc[i], bat));
1251 /* Assign a type number to this cmap */
1252 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 (****) */
1254 /* Check for the correct number of atoms (again) */
1255 if (bt[F_CMAP].nct() != nct)
1257 auto message = gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n", nct, bt[F_CMAP].cmapAngles);
1258 warning_error(wi, message);
1261 std::array<real, MAXFORCEPARAM> forceParam = {NOTSET};
1263 /* Push the bond to the bondlist */
1264 push_bondtype (&(bt[ftype]), InteractionType(atoms, forceParam), nral, ftype, FALSE, line, wi);
1268 static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr,
1270 int type, char *ctype, int ptype,
1272 char *resname, char *name, real m0, real q0,
1273 int typeB, char *ctypeB, real mB, real qB,
1276 int j, resind = 0, resnr;
1280 if (((nr == 0) && (atomnr != 1)) || (nr && (atomnr != at->nr+1)))
1282 auto message = gmx::formatString
1283 ("Atoms in the .top are not numbered consecutively from 1 (rather, "
1284 "atomnr = %d, while at->nr = %d)", atomnr, at->nr);
1285 warning_error_and_exit(wi, message, FARGS);
1288 j = strlen(resnumberic) - 1;
1289 if (isdigit(resnumberic[j]))
1295 ric = resnumberic[j];
1296 if (j == 0 || !isdigit(resnumberic[j-1]))
1298 auto message = gmx::formatString("Invalid residue number '%s' for atom %d",
1299 resnumberic, atomnr);
1300 warning_error_and_exit(wi, message, FARGS);
1303 resnr = strtol(resnumberic, nullptr, 10);
1307 resind = at->atom[nr-1].resind;
1309 if (nr == 0 || strcmp(resname, *at->resinfo[resind].name) != 0 ||
1310 resnr != at->resinfo[resind].nr ||
1311 ric != at->resinfo[resind].ic)
1321 at->nres = resind + 1;
1322 srenew(at->resinfo, at->nres);
1323 at->resinfo[resind].name = put_symtab(symtab, resname);
1324 at->resinfo[resind].nr = resnr;
1325 at->resinfo[resind].ic = ric;
1329 resind = at->atom[at->nr-1].resind;
1332 /* New atom instance
1333 * get new space for arrays
1335 srenew(at->atom, nr+1);
1336 srenew(at->atomname, nr+1);
1337 srenew(at->atomtype, nr+1);
1338 srenew(at->atomtypeB, nr+1);
1341 at->atom[nr].type = type;
1342 at->atom[nr].ptype = ptype;
1343 at->atom[nr].q = q0;
1344 at->atom[nr].m = m0;
1345 at->atom[nr].typeB = typeB;
1346 at->atom[nr].qB = qB;
1347 at->atom[nr].mB = mB;
1349 at->atom[nr].resind = resind;
1350 at->atom[nr].atomnumber = atomicnumber;
1351 at->atomname[nr] = put_symtab(symtab, name);
1352 at->atomtype[nr] = put_symtab(symtab, ctype);
1353 at->atomtypeB[nr] = put_symtab(symtab, ctypeB);
1357 static void push_cg(t_block *block, int *lastindex, int index, int a)
1359 if (((block->nr) && (*lastindex != index)) || (!block->nr))
1361 /* add a new block */
1363 srenew(block->index, block->nr+1);
1365 block->index[block->nr] = a + 1;
1369 void push_atom(t_symtab *symtab, t_block *cgs,
1370 t_atoms *at, PreprocessingAtomTypes *atypes, char *line, int *lastcg,
1374 int cgnumber, atomnr, type, typeB, nscan;
1375 char id[STRLEN], ctype[STRLEN], ctypeB[STRLEN],
1376 resnumberic[STRLEN], resname[STRLEN], name[STRLEN], check[STRLEN];
1377 double m, q, mb, qb;
1378 real m0, q0, mB, qB;
1380 /* Make a shortcut for writing in this molecule */
1383 /* Fixed parameters */
1384 if (sscanf(line, "%s%s%s%s%s%d",
1385 id, ctype, resnumberic, resname, name, &cgnumber) != 6)
1390 sscanf(id, "%d", &atomnr);
1391 if ((type = atypes->atomTypeFromName(ctype)) == NOTSET)
1393 auto message = gmx::formatString("Atomtype %s not found", ctype);
1394 warning_error_and_exit(wi, message, FARGS);
1396 ptype = atypes->atomParticleTypeFromAtomType(type);
1398 /* Set default from type */
1399 q0 = atypes->atomChargeAFromAtomType(type);
1400 m0 = atypes->atomMassAFromAtomType(type);
1405 /* Optional parameters */
1406 nscan = sscanf(line, "%*s%*s%*s%*s%*s%*s%lf%lf%s%lf%lf%s",
1407 &q, &m, ctypeB, &qb, &mb, check);
1409 /* Nasty switch that falls thru all the way down! */
1418 if ((typeB = atypes->atomTypeFromName(ctypeB)) == NOTSET)
1420 auto message = gmx::formatString("Atomtype %s not found", ctypeB);
1421 warning_error_and_exit(wi, message, FARGS);
1423 qB = atypes->atomChargeAFromAtomType(typeB);
1424 mB = atypes->atomMassAFromAtomType(typeB);
1433 warning_error(wi, "Too many parameters");
1441 push_cg(cgs, lastcg, cgnumber, nr);
1443 push_atom_now(symtab, at, atomnr, atypes->atomNumberFromAtomType(type),
1444 type, ctype, ptype, resnumberic,
1445 resname, name, m0, q0, typeB,
1446 typeB == type ? ctype : ctypeB, mB, qB, wi);
1449 void push_molt(t_symtab *symtab,
1450 std::vector<MoleculeInformation> *mol,
1457 if ((sscanf(line, "%s%d", type, &nrexcl)) != 2)
1459 warning_error(wi, "Expected a molecule type name and nrexcl");
1462 /* Test if this moleculetype overwrites another */
1463 const auto found = std::find_if(mol->begin(), mol->end(),
1464 [&type](const auto &m)
1465 { return strcmp(*(m.name), type) == 0; });
1466 if (found != mol->end())
1468 auto message = gmx::formatString("moleculetype %s is redefined", type);
1469 warning_error_and_exit(wi, message, FARGS);
1472 mol->emplace_back();
1473 mol->back().initMolInfo();
1475 /* Fill in the values */
1476 mol->back().name = put_symtab(symtab, type);
1477 mol->back().nrexcl = nrexcl;
1478 mol->back().excl_set = false;
1481 static bool findIfAllNBAtomsMatch(gmx::ArrayRef<const int> atomsFromParameterArray,
1482 gmx::ArrayRef<const int> atomsFromCurrentParameter,
1486 if (atomsFromParameterArray.size() != atomsFromCurrentParameter.size())
1492 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1494 if (at->atom[atomsFromCurrentParameter[i]].typeB != atomsFromParameterArray[i])
1503 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1505 if (at->atom[atomsFromCurrentParameter[i]].type != atomsFromParameterArray[i])
1514 static bool default_nb_params(int ftype, gmx::ArrayRef<InteractionTypeParameters> bt, t_atoms *at,
1515 InteractionType *p, int c_start, bool bB, bool bGenPairs)
1519 InteractionType *pi = nullptr;
1520 int nr = bt[ftype].size();
1521 int nral = NRAL(ftype);
1522 int nrfp = interaction_function[ftype].nrfpA;
1523 int nrfpB = interaction_function[ftype].nrfpB;
1525 if ((!bB && nrfp == 0) || (bB && nrfpB == 0))
1533 /* First test the generated-pair position to save
1534 * time when we have 1000*1000 entries for e.g. OPLS...
1536 ntype = static_cast<int>(std::sqrt(static_cast<double>(nr)));
1537 GMX_ASSERT(ntype * ntype == nr, "Number of pairs of generated non-bonded parameters should be a perfect square");
1540 ti = at->atom[p->ai()].typeB;
1541 tj = at->atom[p->aj()].typeB;
1545 ti = at->atom[p->ai()].type;
1546 tj = at->atom[p->aj()].type;
1548 pi = &(bt[ftype].interactionTypes[ntype*ti+tj]);
1549 if (pi->atoms().ssize() < nral)
1551 /* not initialized yet with atom names */
1556 bFound = ((ti == pi->ai()) && (tj == pi->aj()));
1560 gmx::ArrayRef<const int> paramAtoms = p->atoms();
1561 /* Search explicitly if we didnt find it */
1564 auto foundParameter = std::find_if(bt[ftype].interactionTypes.begin(),
1565 bt[ftype].interactionTypes.end(),
1566 [¶mAtoms, &at, &bB](const auto ¶m)
1567 { return findIfAllNBAtomsMatch(param.atoms(), paramAtoms, at, bB); });
1568 if (foundParameter != bt[ftype].interactionTypes.end())
1571 pi = &(*foundParameter);
1577 gmx::ArrayRef<const real> forceParam = pi->forceParam();
1580 if (nrfp+nrfpB > MAXFORCEPARAM)
1582 gmx_incons("Too many force parameters");
1584 for (int j = c_start; j < nrfpB; j++)
1586 p->setForceParameter(nrfp+j, forceParam[j]);
1591 for (int j = c_start; j < nrfp; j++)
1593 p->setForceParameter(j, forceParam[j]);
1599 for (int j = c_start; j < nrfp; j++)
1601 p->setForceParameter(j, 0.0);
1607 static bool default_cmap_params(gmx::ArrayRef<InteractionTypeParameters> bondtype,
1608 t_atoms *at, PreprocessingAtomTypes *atypes,
1609 InteractionType *p, bool bB,
1610 int *cmap_type, int *nparam_def,
1615 bool bFound = false;
1620 /* Match the current cmap angle against the list of cmap_types */
1621 for (int i = 0; i < bondtype[F_CMAP].nct() && !bFound; i += 6)
1630 (atypes->bondAtomTypeFromAtomType(at->atom[p->ai()].type) == bondtype[F_CMAP].cmapAtomTypes[i]) &&
1631 (atypes->bondAtomTypeFromAtomType(at->atom[p->aj()].type) == bondtype[F_CMAP].cmapAtomTypes[i+1]) &&
1632 (atypes->bondAtomTypeFromAtomType(at->atom[p->ak()].type) == bondtype[F_CMAP].cmapAtomTypes[i+2]) &&
1633 (atypes->bondAtomTypeFromAtomType(at->atom[p->al()].type) == bondtype[F_CMAP].cmapAtomTypes[i+3]) &&
1634 (atypes->bondAtomTypeFromAtomType(at->atom[p->am()].type) == bondtype[F_CMAP].cmapAtomTypes[i+4]))
1636 /* Found cmap torsion */
1638 ct = bondtype[F_CMAP].cmapAtomTypes[i+5];
1644 /* If we did not find a matching type for this cmap torsion */
1647 auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d",
1648 p->ai()+1, p->aj()+1, p->ak()+1, p->al()+1, p->am()+1);
1649 warning_error_and_exit(wi, message, FARGS);
1652 *nparam_def = nparam_found;
1658 /* Returns the number of exact atom type matches, i.e. non wild-card matches,
1659 * returns -1 when there are no matches at all.
1661 static int natom_match(const InteractionType &pi,
1662 int type_i, int type_j, int type_k, int type_l,
1663 const PreprocessingAtomTypes* atypes)
1665 if ((pi.ai() == -1 || atypes->bondAtomTypeFromAtomType(type_i) == pi.ai()) &&
1666 (pi.aj() == -1 || atypes->bondAtomTypeFromAtomType(type_j) == pi.aj()) &&
1667 (pi.ak() == -1 || atypes->bondAtomTypeFromAtomType(type_k) == pi.ak()) &&
1668 (pi.al() == -1 || atypes->bondAtomTypeFromAtomType(type_l) == pi.al()))
1671 (pi.ai() == -1 ? 0 : 1) +
1672 (pi.aj() == -1 ? 0 : 1) +
1673 (pi.ak() == -1 ? 0 : 1) +
1674 (pi.al() == -1 ? 0 : 1);
1682 static int findNumberOfDihedralAtomMatches(const InteractionType ¤tParamFromParameterArray,
1683 const InteractionType ¶meterToAdd,
1685 const PreprocessingAtomTypes *atypes,
1690 return natom_match(currentParamFromParameterArray,
1691 at->atom[parameterToAdd.ai()].typeB,
1692 at->atom[parameterToAdd.aj()].typeB,
1693 at->atom[parameterToAdd.ak()].typeB,
1694 at->atom[parameterToAdd.al()].typeB, atypes);
1698 return natom_match(currentParamFromParameterArray,
1699 at->atom[parameterToAdd.ai()].type,
1700 at->atom[parameterToAdd.aj()].type,
1701 at->atom[parameterToAdd.ak()].type,
1702 at->atom[parameterToAdd.al()].type, atypes);
1706 static bool findIfAllParameterAtomsMatch(gmx::ArrayRef<const int> atomsFromParameterArray,
1707 gmx::ArrayRef<const int> atomsFromCurrentParameter,
1709 const PreprocessingAtomTypes *atypes,
1712 if (atomsFromParameterArray.size() != atomsFromCurrentParameter.size())
1718 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1720 if (atypes->bondAtomTypeFromAtomType(
1721 at->atom[atomsFromCurrentParameter[i]].typeB) != atomsFromParameterArray[i])
1730 for (int i = 0; i < atomsFromCurrentParameter.ssize(); i++)
1732 if (atypes->bondAtomTypeFromAtomType(
1733 at->atom[atomsFromCurrentParameter[i]].type) != atomsFromParameterArray[i])
1742 static std::vector<InteractionType>::iterator
1743 defaultInteractionTypeParameters(int ftype, gmx::ArrayRef<InteractionTypeParameters> bt,
1744 t_atoms *at, PreprocessingAtomTypes *atypes,
1745 const InteractionType &p, bool bB,
1749 int nrfpA = interaction_function[ftype].nrfpA;
1750 int nrfpB = interaction_function[ftype].nrfpB;
1752 if ((!bB && nrfpA == 0) || (bB && nrfpB == 0))
1754 return bt[ftype].interactionTypes.end();
1759 if (ftype == F_PDIHS || ftype == F_RBDIHS || ftype == F_IDIHS || ftype == F_PIDIHS)
1761 int nmatch_max = -1;
1763 /* For dihedrals we allow wildcards. We choose the first type
1764 * that has the most real matches, i.e. non-wildcard matches.
1766 auto prevPos = bt[ftype].interactionTypes.end();
1767 auto pos = bt[ftype].interactionTypes.begin();
1768 while (pos != bt[ftype].interactionTypes.end() && nmatch_max < 4)
1770 pos = std::find_if(bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(),
1771 [&p, &at, &atypes, &bB, &nmatch_max](const auto ¶m)
1772 { return (findNumberOfDihedralAtomMatches(param, p, at, atypes, bB) > nmatch_max); });
1773 if (pos != bt[ftype].interactionTypes.end())
1776 nmatch_max = findNumberOfDihedralAtomMatches(*pos, p, at, atypes, bB);
1780 if (prevPos != bt[ftype].interactionTypes.end())
1784 /* Find additional matches for this dihedral - necessary
1786 * The rule in that case is that additional matches
1787 * HAVE to be on adjacent lines!
1790 /* Continue from current iterator position */
1791 for (auto nextPos = prevPos + 2; (nextPos < bt[ftype].interactionTypes.end()) && bSame; nextPos += 2)
1793 bSame = (prevPos->ai() == nextPos->ai() && prevPos->aj() == nextPos->aj() && prevPos->ak() == nextPos->ak() && prevPos->al() == nextPos->al());
1798 /* nparam_found will be increased as long as the numbers match */
1801 *nparam_def = nparam_found;
1804 else /* Not a dihedral */
1806 gmx::ArrayRef<const int> atomParam = p.atoms();
1807 auto found = std::find_if(bt[ftype].interactionTypes.begin(),
1808 bt[ftype].interactionTypes.end(),
1809 [&atomParam, &at, &atypes, &bB](const auto ¶m)
1810 { return findIfAllParameterAtomsMatch(param.atoms(), atomParam, at, atypes, bB); });
1811 if (found != bt[ftype].interactionTypes.end())
1815 *nparam_def = nparam_found;
1822 void push_bond(Directive d, gmx::ArrayRef<InteractionTypeParameters> bondtype,
1823 gmx::ArrayRef<InteractionTypeParameters> bond,
1824 t_atoms *at, PreprocessingAtomTypes *atypes, char *line,
1825 bool bBonded, bool bGenPairs, real fudgeQQ,
1826 bool bZero, bool *bWarn_copy_A_B,
1829 const char *aaformat[MAXATOMLIST] = {
1837 const char *asformat[MAXATOMLIST] = {
1842 "%*s%*s%*s%*s%*s%*s",
1843 "%*s%*s%*s%*s%*s%*s%*s"
1845 const char *ccformat = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
1846 int nral, nral_fmt, nread, ftype;
1847 char format[STRLEN];
1848 /* One force parameter more, so we can check if we read too many */
1849 double cc[MAXFORCEPARAM+1];
1850 int aa[MAXATOMLIST+1];
1851 bool bFoundA = FALSE, bFoundB = FALSE, bDef, bSwapParity = FALSE;
1852 int nparam_defA, nparam_defB;
1854 nparam_defA = nparam_defB = 0;
1856 ftype = ifunc_index(d, 1);
1858 for (int j = 0; j < nral; j++)
1862 bDef = (NRFP(ftype) > 0);
1864 if (ftype == F_SETTLE)
1866 /* SETTLE acts on 3 atoms, but the topology format only specifies
1867 * the first atom (for historical reasons).
1876 nread = sscanf(line, aaformat[nral_fmt-1],
1877 &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]);
1879 if (ftype == F_SETTLE)
1886 if (nread < nral_fmt)
1891 else if (nread > nral_fmt)
1893 /* this is a hack to allow for virtual sites with swapped parity */
1894 bSwapParity = (aa[nral] < 0);
1897 aa[nral] = -aa[nral];
1899 ftype = ifunc_index(d, aa[nral]);
1908 auto message = gmx::formatString("Negative function types only allowed for %s and %s",
1909 interaction_function[F_VSITE3FAD].longname,
1910 interaction_function[F_VSITE3OUT].longname);
1911 warning_error_and_exit(wi, message, FARGS);
1917 /* Check for double atoms and atoms out of bounds */
1918 for (int i = 0; (i < nral); i++)
1920 if (aa[i] < 1 || aa[i] > at->nr)
1922 auto message = gmx::formatString
1923 ("Atom index (%d) in %s out of bounds (1-%d).\n"
1924 "This probably means that you have inserted topology section \"%s\"\n"
1925 "in a part belonging to a different molecule than you intended to.\n"
1926 "In that case move the \"%s\" section to the right molecule.",
1927 aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
1928 warning_error_and_exit(wi, message, FARGS);
1930 for (int j = i+1; (j < nral); j++)
1932 GMX_ASSERT(j < MAXATOMLIST + 1, "Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy");
1935 auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
1936 if (ftype == F_ANGRES)
1938 /* Since the angle restraints uses 2 pairs of atoms to
1939 * defines an angle between vectors, it can be useful
1940 * to use one atom twice, so we only issue a note here.
1942 warning_note(wi, message);
1946 warning_error(wi, message);
1952 /* default force parameters */
1953 std::vector<int> atoms;
1954 for (int j = 0; (j < nral); j++)
1956 atoms.emplace_back(aa[j]-1);
1958 /* need to have an empty but initialized param array for some reason */
1959 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
1961 /* Get force params for normal and free energy perturbation
1962 * studies, as determined by types!
1964 InteractionType param(atoms, forceParam, "");
1966 std::vector<InteractionType>::iterator foundAParameter = bondtype[ftype].interactionTypes.end();
1967 std::vector<InteractionType>::iterator foundBParameter = bondtype[ftype].interactionTypes.end();
1970 foundAParameter = defaultInteractionTypeParameters(ftype,
1977 if (foundAParameter != bondtype[ftype].interactionTypes.end())
1979 /* Copy the A-state and B-state default parameters. */
1980 GMX_ASSERT(NRFPA(ftype)+NRFPB(ftype) <= MAXFORCEPARAM, "Bonded interactions may have at most 12 parameters");
1981 gmx::ArrayRef<const real> defaultParam = foundAParameter->forceParam();
1982 for (int j = 0; (j < NRFPA(ftype)+NRFPB(ftype)); j++)
1984 param.setForceParameter(j, defaultParam[j]);
1988 else if (NRFPA(ftype) == 0)
1992 foundBParameter = defaultInteractionTypeParameters(ftype,
1999 if (foundBParameter != bondtype[ftype].interactionTypes.end())
2001 /* Copy only the B-state default parameters */
2002 gmx::ArrayRef<const real> defaultParam = foundBParameter->forceParam();
2003 for (int j = NRFPA(ftype); (j < NRFP(ftype)); j++)
2005 param.setForceParameter(j, defaultParam[j]);
2009 else if (NRFPB(ftype) == 0)
2014 else if (ftype == F_LJ14)
2016 bFoundA = default_nb_params(ftype, bondtype, at, ¶m, 0, FALSE, bGenPairs);
2017 bFoundB = default_nb_params(ftype, bondtype, at, ¶m, 0, TRUE, bGenPairs);
2019 else if (ftype == F_LJC14_Q)
2021 /* Fill in the A-state charges as default parameters */
2022 param.setForceParameter(0, fudgeQQ);
2023 param.setForceParameter(1, at->atom[param.ai()].q);
2024 param.setForceParameter(2, at->atom[param.aj()].q);
2025 /* The default LJ parameters are the standard 1-4 parameters */
2026 bFoundA = default_nb_params(F_LJ14, bondtype, at, ¶m, 3, FALSE, bGenPairs);
2029 else if (ftype == F_LJC_PAIRS_NB)
2031 /* Defaults are not supported here */
2037 gmx_incons("Unknown function type in push_bond");
2040 if (nread > nral_fmt)
2042 /* Manually specified parameters - in this case we discard multiple torsion info! */
2044 strcpy(format, asformat[nral_fmt-1]);
2045 strcat(format, ccformat);
2047 nread = sscanf(line, format, &cc[0], &cc[1], &cc[2], &cc[3], &cc[4], &cc[5],
2048 &cc[6], &cc[7], &cc[8], &cc[9], &cc[10], &cc[11], &cc[12]);
2050 if ((nread == NRFPA(ftype)) && (NRFPB(ftype) != 0))
2052 /* We only have to issue a warning if these atoms are perturbed! */
2054 gmx::ArrayRef<const int> paramAtoms = param.atoms();
2055 for (int j = 0; (j < nral); j++)
2057 bPert = bPert || PERTURBED(at->atom[paramAtoms[j]]);
2060 if (bPert && *bWarn_copy_A_B)
2062 auto message = gmx::formatString("Some parameters for bonded interaction involving "
2063 "perturbed atoms are specified explicitly in "
2064 "state A, but not B - copying A to B");
2065 warning(wi, message);
2066 *bWarn_copy_A_B = FALSE;
2069 /* If only the A parameters were specified, copy them to the B state */
2070 /* The B-state parameters correspond to the first nrfpB
2071 * A-state parameters.
2073 for (int j = 0; (j < NRFPB(ftype)); j++)
2075 cc[nread++] = cc[j];
2079 /* If nread was 0 or EOF, no parameters were read => use defaults.
2080 * If nread was nrfpA we copied above so nread=nrfp.
2081 * If nread was nrfp we are cool.
2082 * For F_LJC14_Q we allow supplying fudgeQQ only.
2083 * Anything else is an error!
2085 if ((nread != 0) && (nread != EOF) && (nread != NRFP(ftype)) &&
2086 !(ftype == F_LJC14_Q && nread == 1))
2088 auto message = gmx::formatString
2089 ("Incorrect number of parameters - found %d, expected %d "
2090 "or %d for %s (after the function type).",
2091 nread, NRFPA(ftype), NRFP(ftype), interaction_function[ftype].longname);
2092 warning_error_and_exit(wi, message, FARGS);
2095 for (int j = 0; (j < nread); j++)
2097 param.setForceParameter(j, cc[j]);
2099 /* Check whether we have to use the defaults */
2100 if (nread == NRFP(ftype))
2109 /* nread now holds the number of force parameters read! */
2114 /* When we have multiple terms it would be very dangerous to allow perturbations to a different atom type! */
2115 if (ftype == F_PDIHS)
2117 if ((nparam_defA != nparam_defB) || ((nparam_defA > 1 || nparam_defB > 1) && (foundAParameter != foundBParameter)))
2120 gmx::formatString("Cannot automatically perturb a torsion with multiple terms to different form.\n"
2121 "Please specify perturbed parameters manually for this torsion in your topology!");
2122 warning_error(wi, message);
2126 if (nread > 0 && nread < NRFPA(ftype))
2128 /* Issue an error, do not use defaults */
2129 auto message = gmx::formatString("Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype));
2130 warning_error(wi, message);
2133 if (nread == 0 || nread == EOF)
2137 if (interaction_function[ftype].flags & IF_VSITE)
2139 for (int j = 0; j < MAXFORCEPARAM; j++)
2141 param.setForceParameter(j, NOTSET);
2145 /* flag to swap parity of vsi te construction */
2146 param.setForceParameter(1, -1);
2153 fprintf(stderr, "NOTE: No default %s types, using zeroes\n",
2154 interaction_function[ftype].longname);
2158 auto message = gmx::formatString("No default %s types", interaction_function[ftype].longname);
2159 warning_error(wi, message);
2170 param.setForceParameter(0, 360 - param.c0());
2173 param.setForceParameter(2, -param.c2());
2180 /* We only have to issue a warning if these atoms are perturbed! */
2182 gmx::ArrayRef<const int> paramAtoms = param.atoms();
2183 for (int j = 0; (j < nral); j++)
2185 bPert = bPert || PERTURBED(at->atom[paramAtoms[j]]);
2190 auto message = gmx::formatString("No default %s types for perturbed atoms, "
2191 "using normal values", interaction_function[ftype].longname);
2192 warning(wi, message);
2198 gmx::ArrayRef<const real> paramValue = param.forceParam();
2199 if ((ftype == F_PDIHS || ftype == F_ANGRES || ftype == F_ANGRESZ)
2200 && paramValue[5] != paramValue[2])
2202 auto message = gmx::formatString("%s multiplicity can not be perturbed %f!=%f",
2203 interaction_function[ftype].longname,
2204 paramValue[2], paramValue[5]);
2205 warning_error_and_exit(wi, message, FARGS);
2208 if (IS_TABULATED(ftype) && param.c0() != param.c2())
2210 auto message = gmx::formatString("%s table number can not be perturbed %d!=%d",
2211 interaction_function[ftype].longname,
2212 gmx::roundToInt(param.c0()), gmx::roundToInt(param.c0()));
2213 warning_error_and_exit(wi, message, FARGS);
2216 /* Dont add R-B dihedrals where all parameters are zero (no interaction) */
2217 if (ftype == F_RBDIHS)
2221 for (int i = 0; i < NRFP(ftype); i++)
2223 if (paramValue[i] != 0.0)
2234 /* Put the values in the appropriate arrays */
2235 add_param_to_list (&bond[ftype], param);
2237 /* Push additional torsions from FF for ftype==9 if we have them.
2238 * We have already checked that the A/B states do not differ in this case,
2239 * so we do not have to double-check that again, or the vsite stuff.
2240 * In addition, those torsions cannot be automatically perturbed.
2242 if (bDef && ftype == F_PDIHS)
2244 for (int i = 1; i < nparam_defA; i++)
2246 /* Advance pointer! */
2247 foundAParameter += 2;
2248 gmx::ArrayRef<const real> forceParam = foundAParameter->forceParam();
2249 for (int j = 0; j < (NRFPA(ftype)+NRFPB(ftype)); j++)
2251 param.setForceParameter(j, forceParam[j]);
2253 /* And push the next term for this torsion */
2254 add_param_to_list (&bond[ftype], param);
2259 void push_cmap(Directive d, gmx::ArrayRef<InteractionTypeParameters> bondtype,
2260 gmx::ArrayRef<InteractionTypeParameters> bond,
2261 t_atoms *at, PreprocessingAtomTypes *atypes, char *line,
2264 const char *aaformat[MAXATOMLIST+1] =
2275 int ftype, nral, nread, ncmap_params;
2277 int aa[MAXATOMLIST+1];
2280 ftype = ifunc_index(d, 1);
2284 nread = sscanf(line, aaformat[nral-1],
2285 &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]);
2292 else if (nread == nral)
2294 ftype = ifunc_index(d, 1);
2297 /* Check for double atoms and atoms out of bounds */
2298 for (int i = 0; i < nral; i++)
2300 if (aa[i] < 1 || aa[i] > at->nr)
2302 auto message = gmx::formatString
2303 ("Atom index (%d) in %s out of bounds (1-%d).\n"
2304 "This probably means that you have inserted topology section \"%s\"\n"
2305 "in a part belonging to a different molecule than you intended to.\n"
2306 "In that case move the \"%s\" section to the right molecule.",
2307 aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
2308 warning_error_and_exit(wi, message, FARGS);
2311 for (int j = i+1; (j < nral); j++)
2315 auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
2316 warning_error(wi, message);
2321 /* default force parameters */
2322 std::vector<int> atoms;
2323 for (int j = 0; (j < nral); j++)
2325 atoms.emplace_back(aa[j]-1);
2327 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
2328 InteractionType param(atoms, forceParam, "");
2329 /* Get the cmap type for this cmap angle */
2330 bFound = default_cmap_params(bondtype, at, atypes, ¶m, FALSE, &cmap_type, &ncmap_params, wi);
2332 /* We want exactly one parameter (the cmap type in state A (currently no state B) back */
2333 if (bFound && ncmap_params == 1)
2335 /* Put the values in the appropriate arrays */
2336 param.setForceParameter(0, cmap_type);
2337 add_param_to_list(&bond[ftype], param);
2341 /* This is essentially the same check as in default_cmap_params() done one more time */
2342 auto message = gmx::formatString("Unable to assign a cmap type to torsion %d %d %d %d and %d\n",
2343 param.ai()+1, param.aj()+1, param.ak()+1, param.al()+1, param.am()+1);
2344 warning_error_and_exit(wi, message, FARGS);
2350 void push_vsitesn(Directive d, gmx::ArrayRef<InteractionTypeParameters> bond,
2351 t_atoms *at, char *line,
2355 int type, ftype, n, ret, nj, a;
2357 double *weight = nullptr, weight_tot;
2359 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
2361 ret = sscanf(ptr, "%d%n", &a, &n);
2365 auto message = gmx::formatString("Expected an atom index in section \"%s\"",
2367 warning_error_and_exit(wi, message, FARGS);
2370 sscanf(ptr, "%d%n", &type, &n);
2372 ftype = ifunc_index(d, type);
2373 int firstAtom = a - 1;
2379 ret = sscanf(ptr, "%d%n", &a, &n);
2386 srenew(weight, nj+20);
2395 /* Here we use the A-state mass as a parameter.
2396 * Note that the B-state mass has no influence.
2398 weight[nj] = at->atom[atc[nj]].m;
2402 ret = sscanf(ptr, "%lf%n", &(weight[nj]), &n);
2406 auto message = gmx::formatString
2407 ("No weight or negative weight found for vsiten "
2408 "constructing atom %d (atom index %d)",
2410 warning_error_and_exit(wi, message, FARGS);
2414 auto message = gmx::formatString("Unknown vsiten type %d", type);
2415 warning_error_and_exit(wi, message, FARGS);
2417 weight_tot += weight[nj];
2425 auto message = gmx::formatString("Expected more than one atom index in section \"%s\"",
2427 warning_error_and_exit(wi, message, FARGS);
2430 if (weight_tot == 0)
2432 warning_error_and_exit(wi, "The total mass of the construting atoms is zero", FARGS);
2435 for (int j = 0; j < nj; j++)
2437 std::vector<int> atoms = {firstAtom, atc[j]};
2439 forceParam[1] = weight[j]/weight_tot;
2440 /* Put the values in the appropriate arrays */
2441 add_param_to_list (&bond[ftype], InteractionType(atoms, forceParam));
2448 void push_mol(gmx::ArrayRef<MoleculeInformation> mols, char *pline, int *whichmol,
2454 if (sscanf(pline, "%s%d", type, nrcopies) != 2)
2460 /* Search moleculename.
2461 * Here we originally only did case insensitive matching. But because
2462 * some PDB files can have many chains and use case to generate more
2463 * chain-identifiers, which in turn end up in our moleculetype name,
2464 * we added support for case-sensitivity.
2471 for (const auto &mol : mols)
2473 if (strcmp(type, *(mol.name)) == 0)
2478 if (gmx_strcasecmp(type, *(mol.name)) == 0)
2488 // select the case sensitive match
2489 *whichmol = matchcs;
2493 // avoid matching case-insensitive when we have multiple matches
2496 auto message = gmx::formatString
2497 ("For moleculetype '%s' in [ system ] %d case insensitive "
2498 "matches, but %d case sensitive matches were found. Check "
2499 "the case of the characters in the moleculetypes.",
2501 warning_error_and_exit(wi, message, FARGS);
2505 // select the unique case insensitive match
2506 *whichmol = matchci;
2510 auto message = gmx::formatString("No such moleculetype %s", type);
2511 warning_error_and_exit(wi, message, FARGS);
2516 void push_excl(char *line, gmx::ArrayRef<gmx::ExclusionBlock> b2, warninp *wi)
2520 char base[STRLEN], format[STRLEN];
2522 if (sscanf(line, "%d", &i) == 0)
2527 if ((1 <= i) && (i <= b2.ssize()))
2535 strcpy(base, "%*d");
2538 strcpy(format, base);
2539 strcat(format, "%d");
2540 n = sscanf(line, format, &j);
2543 if ((1 <= j) && (j <= b2.ssize()))
2546 b2[i].atomNumber.push_back(j);
2547 /* also add the reverse exclusion! */
2548 b2[j].atomNumber.push_back(i);
2549 strcat(base, "%*d");
2553 auto message = gmx::formatString("Invalid Atomnr j: %d, b2->nr: %zu\n", j, b2.size());
2554 warning_error_and_exit(wi, message, FARGS);
2561 int add_atomtype_decoupled(t_symtab *symtab, PreprocessingAtomTypes *at,
2562 t_nbparam ***nbparam, t_nbparam ***pair)
2567 /* Define an atom type with all parameters set to zero (no interactions) */
2570 /* Type for decoupled atoms could be anything,
2571 * this should be changed automatically later when required.
2573 atom.ptype = eptAtom;
2575 std::array<real, MAXFORCEPARAM> forceParam = {0.0};
2576 nr = at->addType(symtab, atom, "decoupled", InteractionType({}, forceParam, ""), -1, 0);
2578 /* Add space in the non-bonded parameters matrix */
2579 realloc_nb_params(at, nbparam, pair);
2584 static void convert_pairs_to_pairsQ(gmx::ArrayRef<InteractionTypeParameters> plist,
2585 real fudgeQQ, t_atoms *atoms)
2587 /* Add the pair list to the pairQ list */
2588 std::vector<InteractionType> paramnew;
2590 gmx::ArrayRef<const InteractionType> paramp1 = plist[F_LJ14].interactionTypes;
2591 gmx::ArrayRef<const InteractionType> paramp2 = plist[F_LJC14_Q].interactionTypes;
2593 /* Fill in the new F_LJC14_Q array with the old one. NOTE:
2594 it may be possible to just ADD the converted F_LJ14 array
2595 to the old F_LJC14_Q array, but since we have to create
2596 a new sized memory structure, better just to deep copy it all.
2600 for (const auto ¶m : paramp2)
2602 paramnew.emplace_back(param);
2605 for (const auto ¶m : paramp1)
2607 std::vector<real> forceParam = {
2608 fudgeQQ, atoms->atom[param.ai()].q, atoms->atom[param.aj()].q,
2609 param.c0(), param.c1()
2611 paramnew.emplace_back(InteractionType(param.atoms(), forceParam, ""));
2614 /* now assign the new data to the F_LJC14_Q structure */
2615 plist[F_LJC14_Q].interactionTypes = paramnew;
2617 /* Empty the LJ14 pairlist */
2618 plist[F_LJ14].interactionTypes.clear();
2621 static void generate_LJCpairsNB(MoleculeInformation *mol, int nb_funct, InteractionTypeParameters *nbp, warninp *wi)
2629 atom = mol->atoms.atom;
2631 ntype = static_cast<int>(std::sqrt(static_cast<double>(nbp->size())));
2632 GMX_ASSERT(ntype * ntype == gmx::ssize(*nbp), "Number of pairs of generated non-bonded parameters should be a perfect square");
2634 /* Add a pair interaction for all non-excluded atom pairs */
2636 for (int i = 0; i < n; i++)
2638 for (int j = i+1; j < n; j++)
2641 for (int k = excl->index[i]; k < excl->index[i+1]; k++)
2643 if (excl->a[k] == j)
2650 if (nb_funct != F_LJ)
2652 auto message = gmx::formatString
2653 ("Can only generate non-bonded pair interactions "
2654 "for Van der Waals type Lennard-Jones");
2655 warning_error_and_exit(wi, message, FARGS);
2657 std::vector<int> atoms = {i, j};
2658 std::vector<real> forceParam = {
2661 nbp->interactionTypes[ntype*atom[i].type+atom[j].type].c0(),
2662 nbp->interactionTypes[ntype*atom[i].type+atom[j].type].c1()
2664 add_param_to_list(&mol->plist[F_LJC_PAIRS_NB], InteractionType(atoms, forceParam));
2670 static void set_excl_all(t_blocka *excl)
2674 /* Get rid of the current exclusions and exclude all atom pairs */
2676 excl->nra = nat*nat;
2677 srenew(excl->a, excl->nra);
2679 for (i = 0; i < nat; i++)
2682 for (j = 0; j < nat; j++)
2687 excl->index[nat] = k;
2690 static void decouple_atoms(t_atoms *atoms, int atomtype_decouple,
2691 int couple_lam0, int couple_lam1,
2692 const char *mol_name, warninp *wi)
2696 for (i = 0; i < atoms->nr; i++)
2700 atom = &atoms->atom[i];
2702 if (atom->qB != atom->q || atom->typeB != atom->type)
2704 auto message = gmx::formatString
2705 ("Atom %d in molecule type '%s' has different A and B state "
2706 "charges and/or atom types set in the topology file as well "
2707 "as through the mdp option '%s'. You can not use both "
2708 "these methods simultaneously.",
2709 i + 1, mol_name, "couple-moltype");
2710 warning_error_and_exit(wi, message, FARGS);
2713 if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamVDW)
2717 if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamQ)
2719 atom->type = atomtype_decouple;
2721 if (couple_lam1 == ecouplamNONE || couple_lam1 == ecouplamVDW)
2725 if (couple_lam1 == ecouplamNONE || couple_lam1 == ecouplamQ)
2727 atom->typeB = atomtype_decouple;
2732 void convert_moltype_couple(MoleculeInformation *mol, int atomtype_decouple, real fudgeQQ,
2733 int couple_lam0, int couple_lam1,
2734 bool bCoupleIntra, int nb_funct, InteractionTypeParameters *nbp,
2737 convert_pairs_to_pairsQ(mol->plist, fudgeQQ, &mol->atoms);
2740 generate_LJCpairsNB(mol, nb_funct, nbp, wi);
2741 set_excl_all(&mol->excls);
2743 decouple_atoms(&mol->atoms, atomtype_decouple, couple_lam0, couple_lam1,