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 InteractionsOfType
*interactions
,
72 PreprocessingAtomTypes
*atypes
,
76 real c
, bi
, bj
, ci
, cj
, ci0
, ci1
, ci2
, cj0
, cj1
, cj2
;
78 /* Lean mean shortcuts */
81 interactions
->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 interactions
->interactionTypes
.emplace_back(InteractionOfType({}, 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 interactions
->interactionTypes
.emplace_back(InteractionOfType({}, 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 interactions
->interactionTypes
.emplace_back(InteractionOfType({}, 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 interactions
->interactionTypes
.emplace_back(InteractionOfType({}, 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 InteractionsOfType. */
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
, InteractionsOfType
*interactions
, 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 interactions
->interactionTypes
[nr
*i
+j
].setForceParameter(f
, param
[i
][j
].c
[f
]);
237 interactions
->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 InteractionOfType
interactionType({}, forceParam
, "");
546 batype_nr
= bondAtomType
->addBondAtomType(symtab
, btype
);
548 if ((nr
= at
->atomTypeFromName(type
)) != NOTSET
)
550 auto message
= gmx::formatString
551 ("Atomtype %s was defined previously (e.g. in the forcefield files), "
552 "and has now been defined again. This could happen e.g. if you would "
553 "use a self-contained molecule .itp file that duplicates or replaces "
554 "the contents of the standard force-field files. You should check "
555 "the contents of your files and remove such repetition. If you know "
556 "you should override the previous definition, then you could choose "
557 "to suppress this warning with -maxwarn.", type
);
558 warning(wi
, message
);
559 if ((nr
= at
->setType(nr
, symtab
, *atom
, type
, interactionType
, batype_nr
,
562 auto message
= gmx::formatString("Replacing atomtype %s failed", type
);
563 warning_error_and_exit(wi
, message
, FARGS
);
566 else if ((at
->addType(symtab
, *atom
, type
, interactionType
,
567 batype_nr
, atomnr
)) == NOTSET
)
569 auto message
= gmx::formatString("Adding atomtype %s failed", type
);
570 warning_error_and_exit(wi
, message
, FARGS
);
574 /* Add space in the non-bonded parameters matrix */
575 realloc_nb_params(at
, nbparam
, pair
);
580 //! Return whether the contents of \c a and \c b are the same, considering also reversed order.
581 template <typename T
>
582 static bool equalEitherForwardOrBackward(gmx::ArrayRef
<const T
> a
, gmx::ArrayRef
<const T
> b
)
584 return (std::equal(a
.begin(), a
.end(), b
.begin()) ||
585 std::equal(a
.begin(), a
.end(), b
.rbegin()));
588 static void push_bondtype(InteractionsOfType
*bt
,
589 const InteractionOfType
&b
,
597 int nrfp
= NRFP(ftype
);
599 /* If bAllowRepeat is TRUE, we allow multiple entries as long as they
600 are on directly _adjacent_ lines.
603 /* First check if our atomtypes are _identical_ (not reversed) to the previous
604 entry. If they are not identical we search for earlier duplicates. If they are
605 we can skip it, since we already searched for the first line
609 bool isContinuationOfBlock
= false;
610 if (bAllowRepeat
&& nr
> 1)
612 isContinuationOfBlock
= true;
613 gmx::ArrayRef
<const int> newParAtom
= b
.atoms();
614 gmx::ArrayRef
<const int> sysParAtom
= bt
->interactionTypes
[nr
- 2].atoms();
615 for (int j
= 0; j
< nral
; j
++)
617 if (newParAtom
[j
] != sysParAtom
[j
])
619 isContinuationOfBlock
= false;
624 /* Search for earlier duplicates if this entry was not a continuation
625 from the previous line.
627 bool addBondType
= true;
628 bool haveWarned
= false;
629 bool haveErrored
= false;
630 for (int i
= 0; (i
< nr
); i
++)
632 gmx::ArrayRef
<const int> bParams
= b
.atoms();
633 gmx::ArrayRef
<const int> testParams
= bt
->interactionTypes
[i
].atoms();
634 GMX_RELEASE_ASSERT(bParams
.size() == testParams
.size(), "Number of atoms needs to be the same between parameters");
635 if (equalEitherForwardOrBackward(bParams
, testParams
))
637 GMX_ASSERT(nrfp
<= MAXFORCEPARAM
, "This is ensured in other places, but we need this assert to keep the clang analyzer happy");
638 const bool identicalParameters
= std::equal(bt
->interactionTypes
[i
].forceParam().begin(),
639 bt
->interactionTypes
[i
].forceParam().begin() + nrfp
, b
.forceParam().begin());
641 if (!bAllowRepeat
|| identicalParameters
)
646 if (!identicalParameters
)
650 /* With dihedral type 9 we only allow for repeating
651 * of the same parameters with blocks with 1 entry.
652 * Allowing overriding is too complex to check.
654 if (!isContinuationOfBlock
&& !haveErrored
)
656 warning_error(wi
, "Encountered a second block of parameters for dihedral "
657 "type 9 for the same atoms, with either different parameters "
658 "and/or the first block has multiple lines. This is not supported.");
662 else if (!haveWarned
)
664 auto message
= gmx::formatString
665 ("Bondtype %s was defined previously (e.g. in the forcefield files), "
666 "and has now been defined again. This could happen e.g. if you would "
667 "use a self-contained molecule .itp file that duplicates or replaces "
668 "the contents of the standard force-field files. You should check "
669 "the contents of your files and remove such repetition. If you know "
670 "you should override the previous definition, then you could choose "
671 "to suppress this warning with -maxwarn.%s",
672 interaction_function
[ftype
].longname
,
674 "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive "
675 "lines are combined. Non-consective lines overwrite each other."
677 warning(wi
, message
);
679 fprintf(stderr
, " old: ");
680 gmx::ArrayRef
<const real
> forceParam
= bt
->interactionTypes
[i
].forceParam();
681 for (int j
= 0; j
< nrfp
; j
++)
683 fprintf(stderr
, " %g", forceParam
[j
]);
685 fprintf(stderr
, " \n new: %s\n\n", line
);
691 if (!identicalParameters
&& !bAllowRepeat
)
693 /* Overwrite the parameters with the latest ones */
694 // TODO considering improving the following code by replacing with:
695 // std::copy(b->c, b->c + nrfp, bt->param[i].c);
696 gmx::ArrayRef
<const real
> forceParam
= b
.forceParam();
697 for (int j
= 0; j
< nrfp
; j
++)
699 bt
->interactionTypes
[i
].setForceParameter(j
, forceParam
[j
]);
707 /* fill the arrays up and down */
708 bt
->interactionTypes
.emplace_back(
709 InteractionOfType(b
.atoms(), b
.forceParam(), b
.interactionTypeName()));
710 /* need to store force values because they might change below */
711 std::vector
<real
> forceParam(b
.forceParam().begin(), b
.forceParam().end());
713 /* The definitions of linear angles depend on the order of atoms,
714 * that means that for atoms i-j-k, with certain parameter a, the
715 * corresponding k-j-i angle will have parameter 1-a.
717 if (ftype
== F_LINEAR_ANGLES
)
719 forceParam
[0] = 1- forceParam
[0];
720 forceParam
[2] = 1- forceParam
[2];
722 std::vector
<int> atoms
;
723 gmx::ArrayRef
<const int> oldAtoms
= b
.atoms();
724 for (auto oldAtom
= oldAtoms
.rbegin(); oldAtom
!= oldAtoms
.rend(); oldAtom
++)
726 atoms
.emplace_back(*oldAtom
);
728 bt
->interactionTypes
.emplace_back(InteractionOfType(atoms
, forceParam
, b
.interactionTypeName()));
732 static std::vector
<int> atomTypesFromAtomNames(const PreprocessingAtomTypes
*atomTypes
,
733 const PreprocessingBondAtomType
*bondAtomTypes
,
734 gmx::ArrayRef
<const char[20]> atomNames
,
738 GMX_RELEASE_ASSERT(!(!atomNames
.empty() && !atomTypes
&& !bondAtomTypes
),
739 "Need to have either valid atomtypes or bondatomtypes object");
741 std::vector
<int> atomTypesFromAtomNames
;
742 for (const auto &name
: atomNames
)
744 if (atomTypes
!= nullptr)
746 int atomType
= atomTypes
->atomTypeFromName(name
);
747 if (atomType
== NOTSET
)
749 auto message
= gmx::formatString("Unknown atomtype %s\n", name
);
750 warning_error_and_exit(wi
, message
, FARGS
);
752 atomTypesFromAtomNames
.emplace_back(atomType
);
754 else if (bondAtomTypes
!= nullptr)
756 int atomType
= bondAtomTypes
->bondAtomTypeFromName(name
);
757 if (atomType
== NOTSET
)
759 auto message
= gmx::formatString("Unknown bond_atomtype %s\n", name
);
760 warning_error_and_exit(wi
, message
, FARGS
);
762 atomTypesFromAtomNames
.emplace_back(atomType
);
765 return atomTypesFromAtomNames
;
769 void push_bt(Directive d
,
770 gmx::ArrayRef
<InteractionsOfType
> bt
,
772 PreprocessingAtomTypes
*at
,
773 PreprocessingBondAtomType
*bondAtomType
,
777 const char *formal
[MAXATOMLIST
+1] = {
786 const char *formnl
[MAXATOMLIST
+1] = {
792 "%*s%*s%*s%*s%*s%*s",
793 "%*s%*s%*s%*s%*s%*s%*s"
795 const char *formlf
= "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
796 int i
, ft
, ftype
, nn
, nrfp
, nrfpA
;
798 char alc
[MAXATOMLIST
+1][20];
799 /* One force parameter more, so we can check if we read too many */
800 double c
[MAXFORCEPARAM
+1];
802 if ((bondAtomType
&& at
) || (!bondAtomType
&& !at
))
804 gmx_incons("You should pass either bondAtomType or at to push_bt");
807 /* Make format string (nral ints+functype) */
808 if ((nn
= sscanf(line
, formal
[nral
],
809 alc
[0], alc
[1], alc
[2], alc
[3], alc
[4], alc
[5])) != nral
+1)
811 auto message
= gmx::formatString("Not enough atomtypes (%d instead of %d)", nn
-1, nral
);
812 warning_error(wi
, message
);
816 ft
= strtol(alc
[nral
], nullptr, 10);
817 ftype
= ifunc_index(d
, ft
);
819 nrfpA
= interaction_function
[ftype
].nrfpA
;
820 strcpy(f1
, formnl
[nral
]);
822 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]))
827 /* Copy the B-state from the A-state */
828 copy_B_from_A(ftype
, c
);
834 warning_error(wi
, "Not enough parameters");
836 else if (nn
> nrfpA
&& nn
< nrfp
)
838 warning_error(wi
, "Too many parameters or not enough parameters for topology B");
842 warning_error(wi
, "Too many parameters");
844 for (i
= nn
; (i
< nrfp
); i
++)
850 std::vector
<int> atomTypes
= atomTypesFromAtomNames(at
,
852 gmx::arrayRefFromArray(alc
, nral
),
854 std::array
<real
, MAXFORCEPARAM
> forceParam
;
855 for (int i
= 0; (i
< nrfp
); i
++)
857 forceParam
[i
] = c
[i
];
859 push_bondtype (&(bt
[ftype
]), InteractionOfType(atomTypes
, forceParam
), nral
, ftype
, FALSE
, line
, wi
);
863 void push_dihedraltype(Directive d
, gmx::ArrayRef
<InteractionsOfType
> bt
,
864 PreprocessingBondAtomType
*bondAtomType
, char *line
,
867 const char *formal
[MAXATOMLIST
+1] = {
876 const char *formnl
[MAXATOMLIST
+1] = {
882 "%*s%*s%*s%*s%*s%*s",
883 "%*s%*s%*s%*s%*s%*s%*s"
885 const char *formlf
[MAXFORCEPARAM
] = {
891 "%lf%lf%lf%lf%lf%lf",
892 "%lf%lf%lf%lf%lf%lf%lf",
893 "%lf%lf%lf%lf%lf%lf%lf%lf",
894 "%lf%lf%lf%lf%lf%lf%lf%lf%lf",
895 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
896 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
897 "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
899 int i
, ft
, ftype
, nn
, nrfp
, nrfpA
, nral
;
901 char alc
[MAXATOMLIST
+1][20];
902 double c
[MAXFORCEPARAM
];
905 /* This routine accepts dihedraltypes defined from either 2 or 4 atoms.
907 * We first check for 2 atoms with the 3th column being an integer
908 * defining the type. If this isn't the case, we try it with 4 atoms
909 * and the 5th column defining the dihedral type.
911 nn
= sscanf(line
, formal
[4], alc
[0], alc
[1], alc
[2], alc
[3], alc
[4]);
912 if (nn
>= 3 && strlen(alc
[2]) == 1 && isdigit(alc
[2][0]))
915 ft
= strtol(alc
[nral
], nullptr, 10);
916 /* Move atom types around a bit and use 'X' for wildcard atoms
917 * to create a 4-atom dihedral definition with arbitrary atoms in
920 if (alc
[2][0] == '2')
922 /* improper - the two atomtypes are 1,4. Use wildcards for 2,3 */
923 strcpy(alc
[3], alc
[1]);
924 sprintf(alc
[2], "X");
925 sprintf(alc
[1], "X");
926 /* alc[0] stays put */
930 /* proper - the two atomtypes are 2,3. Use wildcards for 1,4 */
931 sprintf(alc
[3], "X");
932 strcpy(alc
[2], alc
[1]);
933 strcpy(alc
[1], alc
[0]);
934 sprintf(alc
[0], "X");
937 else if (nn
== 5 && strlen(alc
[4]) == 1 && isdigit(alc
[4][0]))
940 ft
= strtol(alc
[nral
], nullptr, 10);
944 auto message
= gmx::formatString("Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn
-1);
945 warning_error(wi
, message
);
951 /* Previously, we have always overwritten parameters if e.g. a torsion
952 with the same atomtypes occurs on multiple lines. However, CHARMM and
953 some other force fields specify multiple dihedrals over some bonds,
954 including cosines with multiplicity 6 and somethimes even higher.
955 Thus, they cannot be represented with Ryckaert-Bellemans terms.
956 To add support for these force fields, Dihedral type 9 is identical to
957 normal proper dihedrals, but repeated entries are allowed.
964 bAllowRepeat
= FALSE
;
968 ftype
= ifunc_index(d
, ft
);
970 nrfpA
= interaction_function
[ftype
].nrfpA
;
972 strcpy(f1
, formnl
[nral
]);
973 strcat(f1
, formlf
[nrfp
-1]);
975 /* Check number of parameters given */
976 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]))
981 /* Copy the B-state from the A-state */
982 copy_B_from_A(ftype
, c
);
988 warning_error(wi
, "Not enough parameters");
990 else if (nn
> nrfpA
&& nn
< nrfp
)
992 warning_error(wi
, "Too many parameters or not enough parameters for topology B");
996 warning_error(wi
, "Too many parameters");
998 for (i
= nn
; (i
< nrfp
); i
++)
1005 std::vector
<int> atoms
;
1006 std::array
<real
, MAXFORCEPARAM
> forceParam
;
1007 for (int i
= 0; (i
< 4); i
++)
1009 if (!strcmp(alc
[i
], "X"))
1011 atoms
.emplace_back(-1);
1016 if ((atomNumber
= bondAtomType
->bondAtomTypeFromName(alc
[i
])) == NOTSET
)
1018 auto message
= gmx::formatString("Unknown bond_atomtype %s", alc
[i
]);
1019 warning_error_and_exit(wi
, message
, FARGS
);
1021 atoms
.emplace_back(atomNumber
);
1024 for (int i
= 0; (i
< nrfp
); i
++)
1026 forceParam
[i
] = c
[i
];
1028 /* Always use 4 atoms here, since we created two wildcard atoms
1029 * if there wasn't of them 4 already.
1031 push_bondtype (&(bt
[ftype
]), InteractionOfType(atoms
, forceParam
), 4, ftype
, bAllowRepeat
, line
, wi
);
1035 void push_nbt(Directive d
, t_nbparam
**nbt
, PreprocessingAtomTypes
*atypes
,
1036 char *pline
, int nb_funct
,
1039 /* swap the atoms */
1040 const char *form3
= "%*s%*s%*s%lf%lf%lf";
1041 const char *form4
= "%*s%*s%*s%lf%lf%lf%lf";
1042 const char *form5
= "%*s%*s%*s%lf%lf%lf%lf%lf";
1043 char a0
[80], a1
[80];
1044 int i
, f
, n
, ftype
, nrfp
;
1051 if (sscanf (pline
, "%s%s%d", a0
, a1
, &f
) != 3)
1057 ftype
= ifunc_index(d
, f
);
1059 if (ftype
!= nb_funct
)
1061 auto message
= gmx::formatString("Trying to add %s while the default nonbond type is %s",
1062 interaction_function
[ftype
].longname
,
1063 interaction_function
[nb_funct
].longname
);
1064 warning_error(wi
, message
);
1068 /* Get the force parameters */
1070 if (ftype
== F_LJ14
)
1072 n
= sscanf(pline
, form4
, &c
[0], &c
[1], &c
[2], &c
[3]);
1078 /* When the B topology parameters are not set,
1079 * copy them from topology A
1081 GMX_ASSERT(nrfp
<= 4, "LJ-14 cannot have more than 4 parameters");
1082 for (i
= n
; i
< nrfp
; i
++)
1087 else if (ftype
== F_LJC14_Q
)
1089 n
= sscanf(pline
, form5
, &c
[0], &c
[1], &c
[2], &c
[3], &dum
);
1092 incorrect_n_param(wi
);
1098 if (sscanf(pline
, form3
, &c
[0], &c
[1], &dum
) != 2)
1100 incorrect_n_param(wi
);
1106 if (sscanf(pline
, form4
, &c
[0], &c
[1], &c
[2], &dum
) != 3)
1108 incorrect_n_param(wi
);
1114 auto message
= gmx::formatString("Number of force parameters for nonbonded interactions is %d", nrfp
);
1115 warning_error_and_exit(wi
, message
, FARGS
);
1117 for (i
= 0; (i
< nrfp
); i
++)
1122 /* Put the parameters in the matrix */
1123 if ((ai
= atypes
->atomTypeFromName(a0
)) == NOTSET
)
1125 auto message
= gmx::formatString("Atomtype %s not found", a0
);
1126 warning_error_and_exit(wi
, message
, FARGS
);
1128 if ((aj
= atypes
->atomTypeFromName(a1
)) == NOTSET
)
1130 auto message
= gmx::formatString("Atomtype %s not found", a1
);
1131 warning_error_and_exit(wi
, message
, FARGS
);
1133 nbp
= &(nbt
[std::max(ai
, aj
)][std::min(ai
, aj
)]);
1138 for (i
= 0; i
< nrfp
; i
++)
1140 bId
= bId
&& (nbp
->c
[i
] == cr
[i
]);
1144 auto message
= gmx::formatString
1145 ("Non-bonded parameters were defined previously (e.g. in the forcefield files), "
1146 "and have now been defined again. This could happen e.g. if you would "
1147 "use a self-contained molecule .itp file that duplicates or replaces "
1148 "the contents of the standard force-field files. You should check "
1149 "the contents of your files and remove such repetition. If you know "
1150 "you should override the previous definitions, then you could choose "
1151 "to suppress this warning with -maxwarn.");
1152 warning(wi
, message
);
1153 fprintf(stderr
, " old:");
1154 for (i
= 0; i
< nrfp
; i
++)
1156 fprintf(stderr
, " %g", nbp
->c
[i
]);
1158 fprintf(stderr
, " new\n%s\n", pline
);
1162 for (i
= 0; i
< nrfp
; i
++)
1169 push_cmaptype(Directive d
,
1170 gmx::ArrayRef
<InteractionsOfType
> bt
,
1172 PreprocessingAtomTypes
*atomtypes
,
1173 PreprocessingBondAtomType
*bondAtomType
,
1177 const char *formal
= "%s%s%s%s%s%s%s%s%n";
1179 int ft
, ftype
, nn
, nrfp
, nrfpA
, nrfpB
;
1180 int start
, nchar_consumed
;
1181 int nxcmap
, nycmap
, ncmap
, read_cmap
, sl
, nct
;
1182 char s
[20], alc
[MAXATOMLIST
+2][20];
1184 /* Keep the compiler happy */
1188 GMX_ASSERT(nral
== 5, "CMAP requires 5 atoms per interaction");
1190 /* Here we can only check for < 8 */
1191 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)
1193 auto message
= gmx::formatString("Incorrect number of atomtypes for cmap (%d instead of 5)", nn
-1);
1194 warning_error(wi
, message
);
1197 start
+= nchar_consumed
;
1199 ft
= strtol(alc
[nral
], nullptr, 10);
1200 nxcmap
= strtol(alc
[nral
+1], nullptr, 10);
1201 nycmap
= strtol(alc
[nral
+2], nullptr, 10);
1203 /* Check for equal grid spacing in x and y dims */
1204 if (nxcmap
!= nycmap
)
1206 auto message
= gmx::formatString("Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap
, nycmap
);
1207 warning_error(wi
, message
);
1210 ncmap
= nxcmap
*nycmap
;
1211 ftype
= ifunc_index(d
, ft
);
1212 nrfpA
= strtol(alc
[6], nullptr, 10)*strtol(alc
[6], nullptr, 10);
1213 nrfpB
= strtol(alc
[7], nullptr, 10)*strtol(alc
[7], nullptr, 10);
1216 /* Read in CMAP parameters */
1218 for (int i
= 0; i
< ncmap
; i
++)
1220 while (isspace(*(line
+start
+sl
)))
1224 nn
= sscanf(line
+start
+sl
, " %s ", s
);
1226 bt
[F_CMAP
].cmap
.emplace_back(strtod(s
, nullptr));
1234 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]);
1235 warning_error(wi
, message
);
1240 /* Check do that we got the number of parameters we expected */
1241 if (read_cmap
== nrfpA
)
1243 for (int i
= 0; i
< ncmap
; i
++)
1245 bt
[F_CMAP
].cmap
.emplace_back(bt
[F_CMAP
].cmap
[i
]);
1250 if (read_cmap
< nrfpA
)
1252 warning_error(wi
, "Not enough cmap parameters");
1254 else if (read_cmap
> nrfpA
&& read_cmap
< nrfp
)
1256 warning_error(wi
, "Too many cmap parameters or not enough parameters for topology B");
1258 else if (read_cmap
> nrfp
)
1260 warning_error(wi
, "Too many cmap parameters");
1265 /* Set grid spacing and the number of grids (we assume these numbers to be the same for all grids
1266 * so we can safely assign them each time
1268 bt
[F_CMAP
].cmakeGridSpacing
= nxcmap
; /* Or nycmap, they need to be equal */
1269 bt
[F_CMAP
].cmapAngles
++; /* Since we are incrementing here, we need to subtract later, see (*****) */
1270 nct
= (nral
+1) * bt
[F_CMAP
].cmapAngles
;
1272 for (int i
= 0; (i
< nral
); i
++)
1274 /* Assign a grid number to each cmap_type */
1275 GMX_RELEASE_ASSERT(bondAtomType
!= nullptr, "Need valid PreprocessingBondAtomType object");
1276 bt
[F_CMAP
].cmapAtomTypes
.emplace_back(bondAtomType
->bondAtomTypeFromName(alc
[i
]));
1279 /* Assign a type number to this cmap */
1280 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 (****) */
1282 /* Check for the correct number of atoms (again) */
1283 if (bt
[F_CMAP
].nct() != nct
)
1285 auto message
= gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n", nct
, bt
[F_CMAP
].cmapAngles
);
1286 warning_error(wi
, message
);
1288 std::vector
<int> atomTypes
= atomTypesFromAtomNames(atomtypes
,
1290 gmx::constArrayRefFromArray(alc
, nral
),
1292 std::array
<real
, MAXFORCEPARAM
> forceParam
= {NOTSET
};
1294 /* Push the bond to the bondlist */
1295 push_bondtype (&(bt
[ftype
]), InteractionOfType(atomTypes
, forceParam
), nral
, ftype
, FALSE
, line
, wi
);
1299 static void push_atom_now(t_symtab
*symtab
, t_atoms
*at
, int atomnr
,
1301 int type
, char *ctype
, int ptype
,
1303 char *resname
, char *name
, real m0
, real q0
,
1304 int typeB
, char *ctypeB
, real mB
, real qB
,
1307 int j
, resind
= 0, resnr
;
1311 if (((nr
== 0) && (atomnr
!= 1)) || (nr
&& (atomnr
!= at
->nr
+1)))
1313 auto message
= gmx::formatString
1314 ("Atoms in the .top are not numbered consecutively from 1 (rather, "
1315 "atomnr = %d, while at->nr = %d)", atomnr
, at
->nr
);
1316 warning_error_and_exit(wi
, message
, FARGS
);
1319 j
= strlen(resnumberic
) - 1;
1320 if (isdigit(resnumberic
[j
]))
1326 ric
= resnumberic
[j
];
1327 if (j
== 0 || !isdigit(resnumberic
[j
-1]))
1329 auto message
= gmx::formatString("Invalid residue number '%s' for atom %d",
1330 resnumberic
, atomnr
);
1331 warning_error_and_exit(wi
, message
, FARGS
);
1334 resnr
= strtol(resnumberic
, nullptr, 10);
1338 resind
= at
->atom
[nr
-1].resind
;
1340 if (nr
== 0 || strcmp(resname
, *at
->resinfo
[resind
].name
) != 0 ||
1341 resnr
!= at
->resinfo
[resind
].nr
||
1342 ric
!= at
->resinfo
[resind
].ic
)
1352 at
->nres
= resind
+ 1;
1353 srenew(at
->resinfo
, at
->nres
);
1354 at
->resinfo
[resind
].name
= put_symtab(symtab
, resname
);
1355 at
->resinfo
[resind
].nr
= resnr
;
1356 at
->resinfo
[resind
].ic
= ric
;
1360 resind
= at
->atom
[at
->nr
-1].resind
;
1363 /* New atom instance
1364 * get new space for arrays
1366 srenew(at
->atom
, nr
+1);
1367 srenew(at
->atomname
, nr
+1);
1368 srenew(at
->atomtype
, nr
+1);
1369 srenew(at
->atomtypeB
, nr
+1);
1372 at
->atom
[nr
].type
= type
;
1373 at
->atom
[nr
].ptype
= ptype
;
1374 at
->atom
[nr
].q
= q0
;
1375 at
->atom
[nr
].m
= m0
;
1376 at
->atom
[nr
].typeB
= typeB
;
1377 at
->atom
[nr
].qB
= qB
;
1378 at
->atom
[nr
].mB
= mB
;
1380 at
->atom
[nr
].resind
= resind
;
1381 at
->atom
[nr
].atomnumber
= atomicnumber
;
1382 at
->atomname
[nr
] = put_symtab(symtab
, name
);
1383 at
->atomtype
[nr
] = put_symtab(symtab
, ctype
);
1384 at
->atomtypeB
[nr
] = put_symtab(symtab
, ctypeB
);
1388 static void push_cg(t_block
*block
, int *lastindex
, int index
, int a
)
1390 if (((block
->nr
) && (*lastindex
!= index
)) || (!block
->nr
))
1392 /* add a new block */
1394 srenew(block
->index
, block
->nr
+1);
1396 block
->index
[block
->nr
] = a
+ 1;
1400 void push_atom(t_symtab
*symtab
, t_block
*cgs
,
1401 t_atoms
*at
, PreprocessingAtomTypes
*atypes
, char *line
, int *lastcg
,
1405 int cgnumber
, atomnr
, type
, typeB
, nscan
;
1406 char id
[STRLEN
], ctype
[STRLEN
], ctypeB
[STRLEN
],
1407 resnumberic
[STRLEN
], resname
[STRLEN
], name
[STRLEN
], check
[STRLEN
];
1408 double m
, q
, mb
, qb
;
1409 real m0
, q0
, mB
, qB
;
1411 /* Make a shortcut for writing in this molecule */
1414 /* Fixed parameters */
1415 if (sscanf(line
, "%s%s%s%s%s%d",
1416 id
, ctype
, resnumberic
, resname
, name
, &cgnumber
) != 6)
1421 sscanf(id
, "%d", &atomnr
);
1422 if ((type
= atypes
->atomTypeFromName(ctype
)) == NOTSET
)
1424 auto message
= gmx::formatString("Atomtype %s not found", ctype
);
1425 warning_error_and_exit(wi
, message
, FARGS
);
1427 ptype
= atypes
->atomParticleTypeFromAtomType(type
);
1429 /* Set default from type */
1430 q0
= atypes
->atomChargeFromAtomType(type
);
1431 m0
= atypes
->atomMassFromAtomType(type
);
1436 /* Optional parameters */
1437 nscan
= sscanf(line
, "%*s%*s%*s%*s%*s%*s%lf%lf%s%lf%lf%s",
1438 &q
, &m
, ctypeB
, &qb
, &mb
, check
);
1440 /* Nasty switch that falls thru all the way down! */
1449 if ((typeB
= atypes
->atomTypeFromName(ctypeB
)) == NOTSET
)
1451 auto message
= gmx::formatString("Atomtype %s not found", ctypeB
);
1452 warning_error_and_exit(wi
, message
, FARGS
);
1454 qB
= atypes
->atomChargeFromAtomType(typeB
);
1455 mB
= atypes
->atomMassFromAtomType(typeB
);
1464 warning_error(wi
, "Too many parameters");
1472 push_cg(cgs
, lastcg
, cgnumber
, nr
);
1474 push_atom_now(symtab
, at
, atomnr
, atypes
->atomNumberFromAtomType(type
),
1475 type
, ctype
, ptype
, resnumberic
,
1476 resname
, name
, m0
, q0
, typeB
,
1477 typeB
== type
? ctype
: ctypeB
, mB
, qB
, wi
);
1480 void push_molt(t_symtab
*symtab
,
1481 std::vector
<MoleculeInformation
> *mol
,
1488 if ((sscanf(line
, "%s%d", type
, &nrexcl
)) != 2)
1490 warning_error(wi
, "Expected a molecule type name and nrexcl");
1493 /* Test if this moleculetype overwrites another */
1494 const auto found
= std::find_if(mol
->begin(), mol
->end(),
1495 [&type
](const auto &m
)
1496 { return strcmp(*(m
.name
), type
) == 0; });
1497 if (found
!= mol
->end())
1499 auto message
= gmx::formatString("moleculetype %s is redefined", type
);
1500 warning_error_and_exit(wi
, message
, FARGS
);
1503 mol
->emplace_back();
1504 mol
->back().initMolInfo();
1506 /* Fill in the values */
1507 mol
->back().name
= put_symtab(symtab
, type
);
1508 mol
->back().nrexcl
= nrexcl
;
1509 mol
->back().excl_set
= false;
1512 static bool findIfAllNBAtomsMatch(gmx::ArrayRef
<const int> atomsFromParameterArray
,
1513 gmx::ArrayRef
<const int> atomsFromCurrentParameter
,
1517 if (atomsFromParameterArray
.size() != atomsFromCurrentParameter
.size())
1523 for (gmx::index i
= 0; i
< atomsFromCurrentParameter
.ssize(); i
++)
1525 if (at
->atom
[atomsFromCurrentParameter
[i
]].typeB
!= atomsFromParameterArray
[i
])
1534 for (gmx::index i
= 0; i
< atomsFromCurrentParameter
.ssize(); i
++)
1536 if (at
->atom
[atomsFromCurrentParameter
[i
]].type
!= atomsFromParameterArray
[i
])
1545 static bool default_nb_params(int ftype
, gmx::ArrayRef
<InteractionsOfType
> bt
, t_atoms
*at
,
1546 InteractionOfType
*p
, int c_start
, bool bB
, bool bGenPairs
)
1550 InteractionOfType
*pi
= nullptr;
1551 int nr
= bt
[ftype
].size();
1552 int nral
= NRAL(ftype
);
1553 int nrfp
= interaction_function
[ftype
].nrfpA
;
1554 int nrfpB
= interaction_function
[ftype
].nrfpB
;
1556 if ((!bB
&& nrfp
== 0) || (bB
&& nrfpB
== 0))
1564 /* First test the generated-pair position to save
1565 * time when we have 1000*1000 entries for e.g. OPLS...
1567 ntype
= static_cast<int>(std::sqrt(static_cast<double>(nr
)));
1568 GMX_ASSERT(ntype
* ntype
== nr
, "Number of pairs of generated non-bonded parameters should be a perfect square");
1571 ti
= at
->atom
[p
->ai()].typeB
;
1572 tj
= at
->atom
[p
->aj()].typeB
;
1576 ti
= at
->atom
[p
->ai()].type
;
1577 tj
= at
->atom
[p
->aj()].type
;
1579 pi
= &(bt
[ftype
].interactionTypes
[ntype
*ti
+tj
]);
1580 if (pi
->atoms().ssize() < nral
)
1582 /* not initialized yet with atom names */
1587 bFound
= ((ti
== pi
->ai()) && (tj
== pi
->aj()));
1591 gmx::ArrayRef
<const int> paramAtoms
= p
->atoms();
1592 /* Search explicitly if we didnt find it */
1595 auto foundParameter
= std::find_if(bt
[ftype
].interactionTypes
.begin(),
1596 bt
[ftype
].interactionTypes
.end(),
1597 [¶mAtoms
, &at
, &bB
](const auto ¶m
)
1598 { return findIfAllNBAtomsMatch(param
.atoms(), paramAtoms
, at
, bB
); });
1599 if (foundParameter
!= bt
[ftype
].interactionTypes
.end())
1602 pi
= &(*foundParameter
);
1608 gmx::ArrayRef
<const real
> forceParam
= pi
->forceParam();
1611 if (nrfp
+nrfpB
> MAXFORCEPARAM
)
1613 gmx_incons("Too many force parameters");
1615 for (int j
= c_start
; j
< nrfpB
; j
++)
1617 p
->setForceParameter(nrfp
+j
, forceParam
[j
]);
1622 for (int j
= c_start
; j
< nrfp
; j
++)
1624 p
->setForceParameter(j
, forceParam
[j
]);
1630 for (int j
= c_start
; j
< nrfp
; j
++)
1632 p
->setForceParameter(j
, 0.0);
1638 static bool default_cmap_params(gmx::ArrayRef
<InteractionsOfType
> bondtype
,
1639 t_atoms
*at
, PreprocessingAtomTypes
*atypes
,
1640 InteractionOfType
*p
, bool bB
,
1641 int *cmap_type
, int *nparam_def
,
1646 bool bFound
= false;
1651 /* Match the current cmap angle against the list of cmap_types */
1652 for (int i
= 0; i
< bondtype
[F_CMAP
].nct() && !bFound
; i
+= 6)
1661 (atypes
->bondAtomTypeFromAtomType(at
->atom
[p
->ai()].type
) == bondtype
[F_CMAP
].cmapAtomTypes
[i
]) &&
1662 (atypes
->bondAtomTypeFromAtomType(at
->atom
[p
->aj()].type
) == bondtype
[F_CMAP
].cmapAtomTypes
[i
+1]) &&
1663 (atypes
->bondAtomTypeFromAtomType(at
->atom
[p
->ak()].type
) == bondtype
[F_CMAP
].cmapAtomTypes
[i
+2]) &&
1664 (atypes
->bondAtomTypeFromAtomType(at
->atom
[p
->al()].type
) == bondtype
[F_CMAP
].cmapAtomTypes
[i
+3]) &&
1665 (atypes
->bondAtomTypeFromAtomType(at
->atom
[p
->am()].type
) == bondtype
[F_CMAP
].cmapAtomTypes
[i
+4]))
1667 /* Found cmap torsion */
1669 ct
= bondtype
[F_CMAP
].cmapAtomTypes
[i
+5];
1675 /* If we did not find a matching type for this cmap torsion */
1678 auto message
= gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d",
1679 p
->ai()+1, p
->aj()+1, p
->ak()+1, p
->al()+1, p
->am()+1);
1680 warning_error_and_exit(wi
, message
, FARGS
);
1683 *nparam_def
= nparam_found
;
1689 /* Returns the number of exact atom type matches, i.e. non wild-card matches,
1690 * returns -1 when there are no matches at all.
1692 static int natom_match(const InteractionOfType
&pi
,
1693 int type_i
, int type_j
, int type_k
, int type_l
,
1694 const PreprocessingAtomTypes
* atypes
)
1696 if ((pi
.ai() == -1 || atypes
->bondAtomTypeFromAtomType(type_i
) == pi
.ai()) &&
1697 (pi
.aj() == -1 || atypes
->bondAtomTypeFromAtomType(type_j
) == pi
.aj()) &&
1698 (pi
.ak() == -1 || atypes
->bondAtomTypeFromAtomType(type_k
) == pi
.ak()) &&
1699 (pi
.al() == -1 || atypes
->bondAtomTypeFromAtomType(type_l
) == pi
.al()))
1702 (pi
.ai() == -1 ? 0 : 1) +
1703 (pi
.aj() == -1 ? 0 : 1) +
1704 (pi
.ak() == -1 ? 0 : 1) +
1705 (pi
.al() == -1 ? 0 : 1);
1713 static int findNumberOfDihedralAtomMatches(const InteractionOfType
¤tParamFromParameterArray
,
1714 const InteractionOfType
¶meterToAdd
,
1716 const PreprocessingAtomTypes
*atypes
,
1721 return natom_match(currentParamFromParameterArray
,
1722 at
->atom
[parameterToAdd
.ai()].typeB
,
1723 at
->atom
[parameterToAdd
.aj()].typeB
,
1724 at
->atom
[parameterToAdd
.ak()].typeB
,
1725 at
->atom
[parameterToAdd
.al()].typeB
, atypes
);
1729 return natom_match(currentParamFromParameterArray
,
1730 at
->atom
[parameterToAdd
.ai()].type
,
1731 at
->atom
[parameterToAdd
.aj()].type
,
1732 at
->atom
[parameterToAdd
.ak()].type
,
1733 at
->atom
[parameterToAdd
.al()].type
, atypes
);
1737 static bool findIfAllParameterAtomsMatch(gmx::ArrayRef
<const int> atomsFromParameterArray
,
1738 gmx::ArrayRef
<const int> atomsFromCurrentParameter
,
1740 const PreprocessingAtomTypes
*atypes
,
1743 if (atomsFromParameterArray
.size() != atomsFromCurrentParameter
.size())
1749 for (gmx::index i
= 0; i
< atomsFromCurrentParameter
.ssize(); i
++)
1751 if (atypes
->bondAtomTypeFromAtomType(
1752 at
->atom
[atomsFromCurrentParameter
[i
]].typeB
) != atomsFromParameterArray
[i
])
1761 for (gmx::index i
= 0; i
< atomsFromCurrentParameter
.ssize(); i
++)
1763 if (atypes
->bondAtomTypeFromAtomType(
1764 at
->atom
[atomsFromCurrentParameter
[i
]].type
) != atomsFromParameterArray
[i
])
1773 static std::vector
<InteractionOfType
>::iterator
1774 defaultInteractionsOfType(int ftype
, gmx::ArrayRef
<InteractionsOfType
> bt
,
1775 t_atoms
*at
, PreprocessingAtomTypes
*atypes
,
1776 const InteractionOfType
&p
, bool bB
,
1780 int nrfpA
= interaction_function
[ftype
].nrfpA
;
1781 int nrfpB
= interaction_function
[ftype
].nrfpB
;
1783 if ((!bB
&& nrfpA
== 0) || (bB
&& nrfpB
== 0))
1785 return bt
[ftype
].interactionTypes
.end();
1790 if (ftype
== F_PDIHS
|| ftype
== F_RBDIHS
|| ftype
== F_IDIHS
|| ftype
== F_PIDIHS
)
1792 int nmatch_max
= -1;
1794 /* For dihedrals we allow wildcards. We choose the first type
1795 * that has the most real matches, i.e. non-wildcard matches.
1797 auto prevPos
= bt
[ftype
].interactionTypes
.end();
1798 auto pos
= bt
[ftype
].interactionTypes
.begin();
1799 while (pos
!= bt
[ftype
].interactionTypes
.end() && nmatch_max
< 4)
1801 pos
= std::find_if(bt
[ftype
].interactionTypes
.begin(), bt
[ftype
].interactionTypes
.end(),
1802 [&p
, &at
, &atypes
, &bB
, &nmatch_max
](const auto ¶m
)
1803 { return (findNumberOfDihedralAtomMatches(param
, p
, at
, atypes
, bB
) > nmatch_max
); });
1804 if (pos
!= bt
[ftype
].interactionTypes
.end())
1807 nmatch_max
= findNumberOfDihedralAtomMatches(*pos
, p
, at
, atypes
, bB
);
1811 if (prevPos
!= bt
[ftype
].interactionTypes
.end())
1815 /* Find additional matches for this dihedral - necessary
1817 * The rule in that case is that additional matches
1818 * HAVE to be on adjacent lines!
1821 //Advance iterator (like std::advance) without incrementing past end (UB)
1822 const auto safeAdvance
= [](auto &it
, auto n
, auto end
) {
1823 it
= end
-it
> n
? it
+n
: end
;
1825 /* Continue from current iterator position */
1826 auto nextPos
= prevPos
;
1827 const auto endIter
= bt
[ftype
].interactionTypes
.end();
1828 safeAdvance(nextPos
, 2, endIter
);
1829 for (; nextPos
< endIter
&& bSame
; safeAdvance(nextPos
, 2, endIter
))
1831 bSame
= (prevPos
->ai() == nextPos
->ai() && prevPos
->aj() == nextPos
->aj() && prevPos
->ak() == nextPos
->ak() && prevPos
->al() == nextPos
->al());
1836 /* nparam_found will be increased as long as the numbers match */
1839 *nparam_def
= nparam_found
;
1842 else /* Not a dihedral */
1844 gmx::ArrayRef
<const int> atomParam
= p
.atoms();
1845 auto found
= std::find_if(bt
[ftype
].interactionTypes
.begin(),
1846 bt
[ftype
].interactionTypes
.end(),
1847 [&atomParam
, &at
, &atypes
, &bB
](const auto ¶m
)
1848 { return findIfAllParameterAtomsMatch(param
.atoms(), atomParam
, at
, atypes
, bB
); });
1849 if (found
!= bt
[ftype
].interactionTypes
.end())
1853 *nparam_def
= nparam_found
;
1860 void push_bond(Directive d
, gmx::ArrayRef
<InteractionsOfType
> bondtype
,
1861 gmx::ArrayRef
<InteractionsOfType
> bond
,
1862 t_atoms
*at
, PreprocessingAtomTypes
*atypes
, char *line
,
1863 bool bBonded
, bool bGenPairs
, real fudgeQQ
,
1864 bool bZero
, bool *bWarn_copy_A_B
,
1867 const char *aaformat
[MAXATOMLIST
] = {
1875 const char *asformat
[MAXATOMLIST
] = {
1880 "%*s%*s%*s%*s%*s%*s",
1881 "%*s%*s%*s%*s%*s%*s%*s"
1883 const char *ccformat
= "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf";
1884 int nral
, nral_fmt
, nread
, ftype
;
1885 char format
[STRLEN
];
1886 /* One force parameter more, so we can check if we read too many */
1887 double cc
[MAXFORCEPARAM
+1];
1888 int aa
[MAXATOMLIST
+1];
1889 bool bFoundA
= FALSE
, bFoundB
= FALSE
, bDef
, bSwapParity
= FALSE
;
1890 int nparam_defA
, nparam_defB
;
1892 nparam_defA
= nparam_defB
= 0;
1894 ftype
= ifunc_index(d
, 1);
1896 for (int j
= 0; j
< nral
; j
++)
1900 bDef
= (NRFP(ftype
) > 0);
1902 if (ftype
== F_SETTLE
)
1904 /* SETTLE acts on 3 atoms, but the topology format only specifies
1905 * the first atom (for historical reasons).
1914 nread
= sscanf(line
, aaformat
[nral_fmt
-1],
1915 &aa
[0], &aa
[1], &aa
[2], &aa
[3], &aa
[4], &aa
[5]);
1917 if (ftype
== F_SETTLE
)
1924 if (nread
< nral_fmt
)
1929 else if (nread
> nral_fmt
)
1931 /* this is a hack to allow for virtual sites with swapped parity */
1932 bSwapParity
= (aa
[nral
] < 0);
1935 aa
[nral
] = -aa
[nral
];
1937 ftype
= ifunc_index(d
, aa
[nral
]);
1946 auto message
= gmx::formatString("Negative function types only allowed for %s and %s",
1947 interaction_function
[F_VSITE3FAD
].longname
,
1948 interaction_function
[F_VSITE3OUT
].longname
);
1949 warning_error_and_exit(wi
, message
, FARGS
);
1955 /* Check for double atoms and atoms out of bounds */
1956 for (int i
= 0; (i
< nral
); i
++)
1958 if (aa
[i
] < 1 || aa
[i
] > at
->nr
)
1960 auto message
= gmx::formatString
1961 ("Atom index (%d) in %s out of bounds (1-%d).\n"
1962 "This probably means that you have inserted topology section \"%s\"\n"
1963 "in a part belonging to a different molecule than you intended to.\n"
1964 "In that case move the \"%s\" section to the right molecule.",
1965 aa
[i
], dir2str(d
), at
->nr
, dir2str(d
), dir2str(d
));
1966 warning_error_and_exit(wi
, message
, FARGS
);
1968 for (int j
= i
+1; (j
< nral
); j
++)
1970 GMX_ASSERT(j
< MAXATOMLIST
+ 1, "Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy");
1973 auto message
= gmx::formatString("Duplicate atom index (%d) in %s", aa
[i
], dir2str(d
));
1974 if (ftype
== F_ANGRES
)
1976 /* Since the angle restraints uses 2 pairs of atoms to
1977 * defines an angle between vectors, it can be useful
1978 * to use one atom twice, so we only issue a note here.
1980 warning_note(wi
, message
);
1984 warning_error(wi
, message
);
1990 /* default force parameters */
1991 std::vector
<int> atoms
;
1992 for (int j
= 0; (j
< nral
); j
++)
1994 atoms
.emplace_back(aa
[j
]-1);
1996 /* need to have an empty but initialized param array for some reason */
1997 std::array
<real
, MAXFORCEPARAM
> forceParam
= {0.0};
1999 /* Get force params for normal and free energy perturbation
2000 * studies, as determined by types!
2002 InteractionOfType
param(atoms
, forceParam
, "");
2004 std::vector
<InteractionOfType
>::iterator foundAParameter
= bondtype
[ftype
].interactionTypes
.end();
2005 std::vector
<InteractionOfType
>::iterator foundBParameter
= bondtype
[ftype
].interactionTypes
.end();
2008 foundAParameter
= defaultInteractionsOfType(ftype
,
2015 if (foundAParameter
!= bondtype
[ftype
].interactionTypes
.end())
2017 /* Copy the A-state and B-state default parameters. */
2018 GMX_ASSERT(NRFPA(ftype
)+NRFPB(ftype
) <= MAXFORCEPARAM
, "Bonded interactions may have at most 12 parameters");
2019 gmx::ArrayRef
<const real
> defaultParam
= foundAParameter
->forceParam();
2020 for (int j
= 0; (j
< NRFPA(ftype
)+NRFPB(ftype
)); j
++)
2022 param
.setForceParameter(j
, defaultParam
[j
]);
2026 else if (NRFPA(ftype
) == 0)
2030 foundBParameter
= defaultInteractionsOfType(ftype
,
2037 if (foundBParameter
!= bondtype
[ftype
].interactionTypes
.end())
2039 /* Copy only the B-state default parameters */
2040 gmx::ArrayRef
<const real
> defaultParam
= foundBParameter
->forceParam();
2041 for (int j
= NRFPA(ftype
); (j
< NRFP(ftype
)); j
++)
2043 param
.setForceParameter(j
, defaultParam
[j
]);
2047 else if (NRFPB(ftype
) == 0)
2052 else if (ftype
== F_LJ14
)
2054 bFoundA
= default_nb_params(ftype
, bondtype
, at
, ¶m
, 0, FALSE
, bGenPairs
);
2055 bFoundB
= default_nb_params(ftype
, bondtype
, at
, ¶m
, 0, TRUE
, bGenPairs
);
2057 else if (ftype
== F_LJC14_Q
)
2059 /* Fill in the A-state charges as default parameters */
2060 param
.setForceParameter(0, fudgeQQ
);
2061 param
.setForceParameter(1, at
->atom
[param
.ai()].q
);
2062 param
.setForceParameter(2, at
->atom
[param
.aj()].q
);
2063 /* The default LJ parameters are the standard 1-4 parameters */
2064 bFoundA
= default_nb_params(F_LJ14
, bondtype
, at
, ¶m
, 3, FALSE
, bGenPairs
);
2067 else if (ftype
== F_LJC_PAIRS_NB
)
2069 /* Defaults are not supported here */
2075 gmx_incons("Unknown function type in push_bond");
2078 if (nread
> nral_fmt
)
2080 /* Manually specified parameters - in this case we discard multiple torsion info! */
2082 strcpy(format
, asformat
[nral_fmt
-1]);
2083 strcat(format
, ccformat
);
2085 nread
= sscanf(line
, format
, &cc
[0], &cc
[1], &cc
[2], &cc
[3], &cc
[4], &cc
[5],
2086 &cc
[6], &cc
[7], &cc
[8], &cc
[9], &cc
[10], &cc
[11], &cc
[12]);
2088 if ((nread
== NRFPA(ftype
)) && (NRFPB(ftype
) != 0))
2090 /* We only have to issue a warning if these atoms are perturbed! */
2092 gmx::ArrayRef
<const int> paramAtoms
= param
.atoms();
2093 for (int j
= 0; (j
< nral
); j
++)
2095 bPert
= bPert
|| PERTURBED(at
->atom
[paramAtoms
[j
]]);
2098 if (bPert
&& *bWarn_copy_A_B
)
2100 auto message
= gmx::formatString("Some parameters for bonded interaction involving "
2101 "perturbed atoms are specified explicitly in "
2102 "state A, but not B - copying A to B");
2103 warning(wi
, message
);
2104 *bWarn_copy_A_B
= FALSE
;
2107 /* If only the A parameters were specified, copy them to the B state */
2108 /* The B-state parameters correspond to the first nrfpB
2109 * A-state parameters.
2111 for (int j
= 0; (j
< NRFPB(ftype
)); j
++)
2113 cc
[nread
++] = cc
[j
];
2117 /* If nread was 0 or EOF, no parameters were read => use defaults.
2118 * If nread was nrfpA we copied above so nread=nrfp.
2119 * If nread was nrfp we are cool.
2120 * For F_LJC14_Q we allow supplying fudgeQQ only.
2121 * Anything else is an error!
2123 if ((nread
!= 0) && (nread
!= EOF
) && (nread
!= NRFP(ftype
)) &&
2124 !(ftype
== F_LJC14_Q
&& nread
== 1))
2126 auto message
= gmx::formatString
2127 ("Incorrect number of parameters - found %d, expected %d "
2128 "or %d for %s (after the function type).",
2129 nread
, NRFPA(ftype
), NRFP(ftype
), interaction_function
[ftype
].longname
);
2130 warning_error_and_exit(wi
, message
, FARGS
);
2133 for (int j
= 0; (j
< nread
); j
++)
2135 param
.setForceParameter(j
, cc
[j
]);
2137 /* Check whether we have to use the defaults */
2138 if (nread
== NRFP(ftype
))
2147 /* nread now holds the number of force parameters read! */
2152 /* When we have multiple terms it would be very dangerous to allow perturbations to a different atom type! */
2153 if (ftype
== F_PDIHS
)
2155 if ((nparam_defA
!= nparam_defB
) || ((nparam_defA
> 1 || nparam_defB
> 1) && (foundAParameter
!= foundBParameter
)))
2158 gmx::formatString("Cannot automatically perturb a torsion with multiple terms to different form.\n"
2159 "Please specify perturbed parameters manually for this torsion in your topology!");
2160 warning_error(wi
, message
);
2164 if (nread
> 0 && nread
< NRFPA(ftype
))
2166 /* Issue an error, do not use defaults */
2167 auto message
= gmx::formatString("Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype
));
2168 warning_error(wi
, message
);
2171 if (nread
== 0 || nread
== EOF
)
2175 if (interaction_function
[ftype
].flags
& IF_VSITE
)
2177 for (int j
= 0; j
< MAXFORCEPARAM
; j
++)
2179 param
.setForceParameter(j
, NOTSET
);
2183 /* flag to swap parity of vsi te construction */
2184 param
.setForceParameter(1, -1);
2191 fprintf(stderr
, "NOTE: No default %s types, using zeroes\n",
2192 interaction_function
[ftype
].longname
);
2196 auto message
= gmx::formatString("No default %s types", interaction_function
[ftype
].longname
);
2197 warning_error(wi
, message
);
2208 param
.setForceParameter(0, 360 - param
.c0());
2211 param
.setForceParameter(2, -param
.c2());
2218 /* We only have to issue a warning if these atoms are perturbed! */
2220 gmx::ArrayRef
<const int> paramAtoms
= param
.atoms();
2221 for (int j
= 0; (j
< nral
); j
++)
2223 bPert
= bPert
|| PERTURBED(at
->atom
[paramAtoms
[j
]]);
2228 auto message
= gmx::formatString("No default %s types for perturbed atoms, "
2229 "using normal values", interaction_function
[ftype
].longname
);
2230 warning(wi
, message
);
2236 gmx::ArrayRef
<const real
> paramValue
= param
.forceParam();
2237 if ((ftype
== F_PDIHS
|| ftype
== F_ANGRES
|| ftype
== F_ANGRESZ
)
2238 && paramValue
[5] != paramValue
[2])
2240 auto message
= gmx::formatString("%s multiplicity can not be perturbed %f!=%f",
2241 interaction_function
[ftype
].longname
,
2242 paramValue
[2], paramValue
[5]);
2243 warning_error_and_exit(wi
, message
, FARGS
);
2246 if (IS_TABULATED(ftype
) && param
.c0() != param
.c2())
2248 auto message
= gmx::formatString("%s table number can not be perturbed %d!=%d",
2249 interaction_function
[ftype
].longname
,
2250 gmx::roundToInt(param
.c0()), gmx::roundToInt(param
.c0()));
2251 warning_error_and_exit(wi
, message
, FARGS
);
2254 /* Dont add R-B dihedrals where all parameters are zero (no interaction) */
2255 if (ftype
== F_RBDIHS
)
2259 for (int i
= 0; i
< NRFP(ftype
); i
++)
2261 if (paramValue
[i
] != 0.0)
2272 /* Put the values in the appropriate arrays */
2273 add_param_to_list (&bond
[ftype
], param
);
2275 /* Push additional torsions from FF for ftype==9 if we have them.
2276 * We have already checked that the A/B states do not differ in this case,
2277 * so we do not have to double-check that again, or the vsite stuff.
2278 * In addition, those torsions cannot be automatically perturbed.
2280 if (bDef
&& ftype
== F_PDIHS
)
2282 for (int i
= 1; i
< nparam_defA
; i
++)
2284 /* Advance pointer! */
2285 foundAParameter
+= 2;
2286 gmx::ArrayRef
<const real
> forceParam
= foundAParameter
->forceParam();
2287 for (int j
= 0; j
< (NRFPA(ftype
)+NRFPB(ftype
)); j
++)
2289 param
.setForceParameter(j
, forceParam
[j
]);
2291 /* And push the next term for this torsion */
2292 add_param_to_list (&bond
[ftype
], param
);
2297 void push_cmap(Directive d
, gmx::ArrayRef
<InteractionsOfType
> bondtype
,
2298 gmx::ArrayRef
<InteractionsOfType
> bond
,
2299 t_atoms
*at
, PreprocessingAtomTypes
*atypes
, char *line
,
2302 const char *aaformat
[MAXATOMLIST
+1] =
2313 int ftype
, nral
, nread
, ncmap_params
;
2315 int aa
[MAXATOMLIST
+1];
2318 ftype
= ifunc_index(d
, 1);
2322 nread
= sscanf(line
, aaformat
[nral
-1],
2323 &aa
[0], &aa
[1], &aa
[2], &aa
[3], &aa
[4], &aa
[5]);
2330 else if (nread
== nral
)
2332 ftype
= ifunc_index(d
, 1);
2335 /* Check for double atoms and atoms out of bounds */
2336 for (int i
= 0; i
< nral
; i
++)
2338 if (aa
[i
] < 1 || aa
[i
] > at
->nr
)
2340 auto message
= gmx::formatString
2341 ("Atom index (%d) in %s out of bounds (1-%d).\n"
2342 "This probably means that you have inserted topology section \"%s\"\n"
2343 "in a part belonging to a different molecule than you intended to.\n"
2344 "In that case move the \"%s\" section to the right molecule.",
2345 aa
[i
], dir2str(d
), at
->nr
, dir2str(d
), dir2str(d
));
2346 warning_error_and_exit(wi
, message
, FARGS
);
2349 for (int j
= i
+1; (j
< nral
); j
++)
2353 auto message
= gmx::formatString("Duplicate atom index (%d) in %s", aa
[i
], dir2str(d
));
2354 warning_error(wi
, message
);
2359 /* default force parameters */
2360 std::vector
<int> atoms
;
2361 for (int j
= 0; (j
< nral
); j
++)
2363 atoms
.emplace_back(aa
[j
]-1);
2365 std::array
<real
, MAXFORCEPARAM
> forceParam
= {0.0};
2366 InteractionOfType
param(atoms
, forceParam
, "");
2367 /* Get the cmap type for this cmap angle */
2368 bFound
= default_cmap_params(bondtype
, at
, atypes
, ¶m
, FALSE
, &cmap_type
, &ncmap_params
, wi
);
2370 /* We want exactly one parameter (the cmap type in state A (currently no state B) back */
2371 if (bFound
&& ncmap_params
== 1)
2373 /* Put the values in the appropriate arrays */
2374 param
.setForceParameter(0, cmap_type
);
2375 add_param_to_list(&bond
[ftype
], param
);
2379 /* This is essentially the same check as in default_cmap_params() done one more time */
2380 auto message
= gmx::formatString("Unable to assign a cmap type to torsion %d %d %d %d and %d\n",
2381 param
.ai()+1, param
.aj()+1, param
.ak()+1, param
.al()+1, param
.am()+1);
2382 warning_error_and_exit(wi
, message
, FARGS
);
2388 void push_vsitesn(Directive d
, gmx::ArrayRef
<InteractionsOfType
> bond
,
2389 t_atoms
*at
, char *line
,
2393 int type
, ftype
, n
, ret
, nj
, a
;
2395 double *weight
= nullptr, weight_tot
;
2397 std::array
<real
, MAXFORCEPARAM
> forceParam
= {0.0};
2399 ret
= sscanf(ptr
, "%d%n", &a
, &n
);
2403 auto message
= gmx::formatString("Expected an atom index in section \"%s\"",
2405 warning_error_and_exit(wi
, message
, FARGS
);
2408 sscanf(ptr
, "%d%n", &type
, &n
);
2410 ftype
= ifunc_index(d
, type
);
2411 int firstAtom
= a
- 1;
2417 ret
= sscanf(ptr
, "%d%n", &a
, &n
);
2424 srenew(weight
, nj
+20);
2433 /* Here we use the A-state mass as a parameter.
2434 * Note that the B-state mass has no influence.
2436 weight
[nj
] = at
->atom
[atc
[nj
]].m
;
2440 ret
= sscanf(ptr
, "%lf%n", &(weight
[nj
]), &n
);
2444 auto message
= gmx::formatString
2445 ("No weight or negative weight found for vsiten "
2446 "constructing atom %d (atom index %d)",
2448 warning_error_and_exit(wi
, message
, FARGS
);
2452 auto message
= gmx::formatString("Unknown vsiten type %d", type
);
2453 warning_error_and_exit(wi
, message
, FARGS
);
2455 weight_tot
+= weight
[nj
];
2463 auto message
= gmx::formatString("Expected more than one atom index in section \"%s\"",
2465 warning_error_and_exit(wi
, message
, FARGS
);
2468 if (weight_tot
== 0)
2470 warning_error_and_exit(wi
, "The total mass of the construting atoms is zero", FARGS
);
2473 for (int j
= 0; j
< nj
; j
++)
2475 std::vector
<int> atoms
= {firstAtom
, atc
[j
]};
2477 forceParam
[1] = weight
[j
]/weight_tot
;
2478 /* Put the values in the appropriate arrays */
2479 add_param_to_list (&bond
[ftype
], InteractionOfType(atoms
, forceParam
));
2486 void push_mol(gmx::ArrayRef
<MoleculeInformation
> mols
, char *pline
, int *whichmol
,
2492 if (sscanf(pline
, "%s%d", type
, nrcopies
) != 2)
2498 /* Search moleculename.
2499 * Here we originally only did case insensitive matching. But because
2500 * some PDB files can have many chains and use case to generate more
2501 * chain-identifiers, which in turn end up in our moleculetype name,
2502 * we added support for case-sensitivity.
2509 for (const auto &mol
: mols
)
2511 if (strcmp(type
, *(mol
.name
)) == 0)
2516 if (gmx_strcasecmp(type
, *(mol
.name
)) == 0)
2526 // select the case sensitive match
2527 *whichmol
= matchcs
;
2531 // avoid matching case-insensitive when we have multiple matches
2534 auto message
= gmx::formatString
2535 ("For moleculetype '%s' in [ system ] %d case insensitive "
2536 "matches, but %d case sensitive matches were found. Check "
2537 "the case of the characters in the moleculetypes.",
2539 warning_error_and_exit(wi
, message
, FARGS
);
2543 // select the unique case insensitive match
2544 *whichmol
= matchci
;
2548 auto message
= gmx::formatString("No such moleculetype %s", type
);
2549 warning_error_and_exit(wi
, message
, FARGS
);
2554 void push_excl(char *line
, gmx::ArrayRef
<gmx::ExclusionBlock
> b2
, warninp
*wi
)
2558 char base
[STRLEN
], format
[STRLEN
];
2560 if (sscanf(line
, "%d", &i
) == 0)
2565 if ((1 <= i
) && (i
<= b2
.ssize()))
2573 strcpy(base
, "%*d");
2576 strcpy(format
, base
);
2577 strcat(format
, "%d");
2578 n
= sscanf(line
, format
, &j
);
2581 if ((1 <= j
) && (j
<= b2
.ssize()))
2584 b2
[i
].atomNumber
.push_back(j
);
2585 /* also add the reverse exclusion! */
2586 b2
[j
].atomNumber
.push_back(i
);
2587 strcat(base
, "%*d");
2591 auto message
= gmx::formatString("Invalid Atomnr j: %d, b2->nr: %zu\n", j
, b2
.size());
2592 warning_error_and_exit(wi
, message
, FARGS
);
2599 int add_atomtype_decoupled(t_symtab
*symtab
, PreprocessingAtomTypes
*at
,
2600 t_nbparam
***nbparam
, t_nbparam
***pair
)
2605 /* Define an atom type with all parameters set to zero (no interactions) */
2608 /* Type for decoupled atoms could be anything,
2609 * this should be changed automatically later when required.
2611 atom
.ptype
= eptAtom
;
2613 std::array
<real
, MAXFORCEPARAM
> forceParam
= {0.0};
2614 nr
= at
->addType(symtab
, atom
, "decoupled", InteractionOfType({}, forceParam
, ""), -1, 0);
2616 /* Add space in the non-bonded parameters matrix */
2617 realloc_nb_params(at
, nbparam
, pair
);
2622 static void convert_pairs_to_pairsQ(gmx::ArrayRef
<InteractionsOfType
> interactions
,
2623 real fudgeQQ
, t_atoms
*atoms
)
2625 /* Add the pair list to the pairQ list */
2626 std::vector
<InteractionOfType
> paramnew
;
2628 gmx::ArrayRef
<const InteractionOfType
> paramp1
= interactions
[F_LJ14
].interactionTypes
;
2629 gmx::ArrayRef
<const InteractionOfType
> paramp2
= interactions
[F_LJC14_Q
].interactionTypes
;
2631 /* Fill in the new F_LJC14_Q array with the old one. NOTE:
2632 it may be possible to just ADD the converted F_LJ14 array
2633 to the old F_LJC14_Q array, but since we have to create
2634 a new sized memory structure, better just to deep copy it all.
2638 for (const auto ¶m
: paramp2
)
2640 paramnew
.emplace_back(param
);
2643 for (const auto ¶m
: paramp1
)
2645 std::vector
<real
> forceParam
= {
2646 fudgeQQ
, atoms
->atom
[param
.ai()].q
, atoms
->atom
[param
.aj()].q
,
2647 param
.c0(), param
.c1()
2649 paramnew
.emplace_back(InteractionOfType(param
.atoms(), forceParam
, ""));
2652 /* now assign the new data to the F_LJC14_Q structure */
2653 interactions
[F_LJC14_Q
].interactionTypes
= paramnew
;
2655 /* Empty the LJ14 pairlist */
2656 interactions
[F_LJ14
].interactionTypes
.clear();
2659 static void generate_LJCpairsNB(MoleculeInformation
*mol
, int nb_funct
, InteractionsOfType
*nbp
, warninp
*wi
)
2667 atom
= mol
->atoms
.atom
;
2669 ntype
= static_cast<int>(std::sqrt(static_cast<double>(nbp
->size())));
2670 GMX_ASSERT(ntype
* ntype
== gmx::ssize(*nbp
), "Number of pairs of generated non-bonded parameters should be a perfect square");
2672 /* Add a pair interaction for all non-excluded atom pairs */
2674 for (int i
= 0; i
< n
; i
++)
2676 for (int j
= i
+1; j
< n
; j
++)
2679 for (int k
= excl
->index
[i
]; k
< excl
->index
[i
+1]; k
++)
2681 if (excl
->a
[k
] == j
)
2688 if (nb_funct
!= F_LJ
)
2690 auto message
= gmx::formatString
2691 ("Can only generate non-bonded pair interactions "
2692 "for Van der Waals type Lennard-Jones");
2693 warning_error_and_exit(wi
, message
, FARGS
);
2695 std::vector
<int> atoms
= {i
, j
};
2696 std::vector
<real
> forceParam
= {
2699 nbp
->interactionTypes
[ntype
*atom
[i
].type
+atom
[j
].type
].c0(),
2700 nbp
->interactionTypes
[ntype
*atom
[i
].type
+atom
[j
].type
].c1()
2702 add_param_to_list(&mol
->interactions
[F_LJC_PAIRS_NB
], InteractionOfType(atoms
, forceParam
));
2708 static void set_excl_all(t_blocka
*excl
)
2712 /* Get rid of the current exclusions and exclude all atom pairs */
2714 excl
->nra
= nat
*nat
;
2715 srenew(excl
->a
, excl
->nra
);
2717 for (i
= 0; i
< nat
; i
++)
2720 for (j
= 0; j
< nat
; j
++)
2725 excl
->index
[nat
] = k
;
2728 static void decouple_atoms(t_atoms
*atoms
, int atomtype_decouple
,
2729 int couple_lam0
, int couple_lam1
,
2730 const char *mol_name
, warninp
*wi
)
2734 for (i
= 0; i
< atoms
->nr
; i
++)
2738 atom
= &atoms
->atom
[i
];
2740 if (atom
->qB
!= atom
->q
|| atom
->typeB
!= atom
->type
)
2742 auto message
= gmx::formatString
2743 ("Atom %d in molecule type '%s' has different A and B state "
2744 "charges and/or atom types set in the topology file as well "
2745 "as through the mdp option '%s'. You can not use both "
2746 "these methods simultaneously.",
2747 i
+ 1, mol_name
, "couple-moltype");
2748 warning_error_and_exit(wi
, message
, FARGS
);
2751 if (couple_lam0
== ecouplamNONE
|| couple_lam0
== ecouplamVDW
)
2755 if (couple_lam0
== ecouplamNONE
|| couple_lam0
== ecouplamQ
)
2757 atom
->type
= atomtype_decouple
;
2759 if (couple_lam1
== ecouplamNONE
|| couple_lam1
== ecouplamVDW
)
2763 if (couple_lam1
== ecouplamNONE
|| couple_lam1
== ecouplamQ
)
2765 atom
->typeB
= atomtype_decouple
;
2770 void convert_moltype_couple(MoleculeInformation
*mol
, int atomtype_decouple
, real fudgeQQ
,
2771 int couple_lam0
, int couple_lam1
,
2772 bool bCoupleIntra
, int nb_funct
, InteractionsOfType
*nbp
,
2775 convert_pairs_to_pairsQ(mol
->interactions
, fudgeQQ
, &mol
->atoms
);
2778 generate_LJCpairsNB(mol
, nb_funct
, nbp
, wi
);
2779 set_excl_all(&mol
->excls
);
2781 decouple_atoms(&mol
->atoms
, atomtype_decouple
, couple_lam0
, couple_lam1
,