54e15169ff25a1b52eba5f40c74a039dc0ccaca6
[alexxy/gromacs.git] / src / gromacs / gmxpreprocess / topio.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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 by the GROMACS development team.
7  * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
8  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9  * and including many others, as listed in the AUTHORS file in the
10  * top-level source directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38 #include "gmxpre.h"
39
40 #include "gromacs/utility/enumerationhelpers.h"
41 #include "gromacs/utility/stringutil.h"
42 #include "topio.h"
43
44 #include <cassert>
45 #include <cctype>
46 #include <cerrno>
47 #include <cmath>
48 #include <cstdio>
49 #include <cstdlib>
50 #include <cstring>
51
52 #include <algorithm>
53 #include <memory>
54 #include <unordered_set>
55
56 #include <sys/types.h>
57
58 #include "gromacs/fileio/gmxfio.h"
59 #include "gromacs/fileio/warninp.h"
60 #include "gromacs/gmxpreprocess/gmxcpp.h"
61 #include "gromacs/gmxpreprocess/gpp_atomtype.h"
62 #include "gromacs/gmxpreprocess/gpp_bond_atomtype.h"
63 #include "gromacs/gmxpreprocess/gpp_nextnb.h"
64 #include "gromacs/gmxpreprocess/grompp_impl.h"
65 #include "gromacs/gmxpreprocess/readir.h"
66 #include "gromacs/gmxpreprocess/topdirs.h"
67 #include "gromacs/gmxpreprocess/toppush.h"
68 #include "gromacs/gmxpreprocess/topshake.h"
69 #include "gromacs/gmxpreprocess/toputil.h"
70 #include "gromacs/gmxpreprocess/vsite_parm.h"
71 #include "gromacs/math/units.h"
72 #include "gromacs/math/utilities.h"
73 #include "gromacs/mdtypes/inputrec.h"
74 #include "gromacs/mdtypes/md_enums.h"
75 #include "gromacs/pbcutil/pbc.h"
76 #include "gromacs/topology/block.h"
77 #include "gromacs/topology/exclusionblocks.h"
78 #include "gromacs/topology/ifunc.h"
79 #include "gromacs/topology/symtab.h"
80 #include "gromacs/topology/topology.h"
81 #include "gromacs/utility/cstringutil.h"
82 #include "gromacs/utility/fatalerror.h"
83 #include "gromacs/utility/futil.h"
84 #include "gromacs/utility/gmxassert.h"
85 #include "gromacs/utility/logger.h"
86 #include "gromacs/utility/pleasecite.h"
87 #include "gromacs/utility/smalloc.h"
88
89 #define OPENDIR '['  /* starting sign for directive */
90 #define CLOSEDIR ']' /* ending sign for directive   */
91
92 static void gen_pairs(const InteractionsOfType& nbs, InteractionsOfType* pairs, real fudge, CombinationRule comb)
93 {
94     real scaling;
95     int  ntp = nbs.size();
96     int  nnn = static_cast<int>(std::sqrt(static_cast<double>(ntp)));
97     GMX_ASSERT(nnn * nnn == ntp,
98                "Number of pairs of generated non-bonded parameters should be a perfect square");
99     int nrfp  = NRFP(F_LJ);
100     int nrfpA = interaction_function[F_LJ14].nrfpA;
101     int nrfpB = interaction_function[F_LJ14].nrfpB;
102
103     if ((nrfp != nrfpA) || (nrfpA != nrfpB))
104     {
105         gmx_incons("Number of force parameters in gen_pairs wrong");
106     }
107
108     fprintf(stderr, "Generating 1-4 interactions: fudge = %g\n", fudge);
109     pairs->interactionTypes.clear();
110     int                             i = 0;
111     std::array<int, 2>              atomNumbers;
112     std::array<real, MAXFORCEPARAM> forceParam = { NOTSET };
113     for (const auto& type : nbs.interactionTypes)
114     {
115         /* Copy type.atoms */
116         atomNumbers = { i / nnn, i % nnn };
117         /* Copy normal and FEP parameters and multiply by fudge factor */
118         gmx::ArrayRef<const real> existingParam = type.forceParam();
119         GMX_RELEASE_ASSERT(2 * nrfp <= MAXFORCEPARAM,
120                            "Can't have more parameters than half of maximum p  arameter number");
121         for (int j = 0; j < nrfp; j++)
122         {
123             /* If we are using sigma/epsilon values, only the epsilon values
124              * should be scaled, but not sigma.
125              * The sigma values have even indices 0,2, etc.
126              */
127             if ((comb == CombinationRule::Arithmetic || comb == CombinationRule::GeomSigEps)
128                 && (j % 2 == 0))
129             {
130                 scaling = 1.0;
131             }
132             else
133             {
134                 scaling = fudge;
135             }
136
137             forceParam[j]        = scaling * existingParam[j];
138             forceParam[nrfp + j] = scaling * existingParam[j];
139         }
140         pairs->interactionTypes.emplace_back(InteractionOfType(atomNumbers, forceParam));
141         i++;
142     }
143 }
144
145 double check_mol(const gmx_mtop_t* mtop, warninp* wi)
146 {
147     char   buf[256];
148     int    i, ri, pt;
149     double q;
150     real   m, mB;
151
152     /* Check mass and charge */
153     q = 0.0;
154
155     for (const gmx_molblock_t& molb : mtop->molblock)
156     {
157         const t_atoms* atoms = &mtop->moltype[molb.type].atoms;
158         for (i = 0; (i < atoms->nr); i++)
159         {
160             q += molb.nmol * atoms->atom[i].q;
161             m  = atoms->atom[i].m;
162             mB = atoms->atom[i].mB;
163             pt = atoms->atom[i].ptype;
164             /* If the particle is an atom or a nucleus it must have a mass,
165              * else, if it is a shell, a vsite or a bondshell it can have mass zero
166              */
167             if (((m <= 0.0) || (mB <= 0.0)) && ((pt == eptAtom) || (pt == eptNucleus)))
168             {
169                 ri = atoms->atom[i].resind;
170                 sprintf(buf,
171                         "atom %s (Res %s-%d) has mass %g (state A) / %g (state B)\n",
172                         *(atoms->atomname[i]),
173                         *(atoms->resinfo[ri].name),
174                         atoms->resinfo[ri].nr,
175                         m,
176                         mB);
177                 warning_error(wi, buf);
178             }
179             else if (((m != 0) || (mB != 0)) && (pt == eptVSite))
180             {
181                 ri = atoms->atom[i].resind;
182                 sprintf(buf,
183                         "virtual site %s (Res %s-%d) has non-zero mass %g (state A) / %g (state "
184                         "B)\n"
185                         "     Check your topology.\n",
186                         *(atoms->atomname[i]),
187                         *(atoms->resinfo[ri].name),
188                         atoms->resinfo[ri].nr,
189                         m,
190                         mB);
191                 warning_error(wi, buf);
192                 /* The following statements make LINCS break! */
193                 /* atoms->atom[i].m=0; */
194             }
195         }
196     }
197     return q;
198 }
199
200 /*! \brief Returns the rounded charge of a molecule, when close to integer, otherwise returns the original charge.
201  *
202  * The results of this routine are only used for checking and for
203  * printing warning messages. Thus we can assume that charges of molecules
204  * should be integer. If the user wanted non-integer molecular charge,
205  * an undesired warning is printed and the user should use grompp -maxwarn 1.
206  *
207  * \param qMol     The total, unrounded, charge of the molecule
208  * \param sumAbsQ  The sum of absolute values of the charges, used for determining the tolerance for the rounding.
209  */
210 static double roundedMoleculeCharge(double qMol, double sumAbsQ)
211 {
212     /* We use a tolerance of 1e-6 for inaccuracies beyond the 6th decimal
213      * of the charges for ascii float truncation in the topology files.
214      * Although the summation here uses double precision, the charges
215      * are read and stored in single precision when real=float. This can
216      * lead to rounding errors of half the least significant bit.
217      * Note that, unfortunately, we can not assume addition of random
218      * rounding errors. It is not entirely unlikely that many charges
219      * have a near half-bit rounding error with the same sign.
220      */
221     double tolAbs = 1e-6;
222     double tol    = std::max(tolAbs, 0.5 * GMX_REAL_EPS * sumAbsQ);
223     double qRound = std::round(qMol);
224     if (std::abs(qMol - qRound) <= tol)
225     {
226         return qRound;
227     }
228     else
229     {
230         return qMol;
231     }
232 }
233
234 static void sum_q(const t_atoms* atoms, int numMols, double* qTotA, double* qTotB)
235 {
236     /* sum charge */
237     double qmolA    = 0;
238     double qmolB    = 0;
239     double sumAbsQA = 0;
240     double sumAbsQB = 0;
241     for (int i = 0; i < atoms->nr; i++)
242     {
243         qmolA += atoms->atom[i].q;
244         qmolB += atoms->atom[i].qB;
245         sumAbsQA += std::abs(atoms->atom[i].q);
246         sumAbsQB += std::abs(atoms->atom[i].qB);
247     }
248
249     *qTotA += numMols * roundedMoleculeCharge(qmolA, sumAbsQA);
250     *qTotB += numMols * roundedMoleculeCharge(qmolB, sumAbsQB);
251 }
252
253 static void get_nbparm(char* nb_str, char* comb_str, VanDerWaalsPotential* nb, CombinationRule* comb, warninp* wi)
254 {
255     *nb = VanDerWaalsPotential::Count;
256     for (auto i : gmx::EnumerationArray<VanDerWaalsPotential, bool>::keys())
257     {
258         if (gmx_strcasecmp(nb_str, enumValueToString(i)) == 0)
259         {
260             *nb = i;
261         }
262     }
263     if (*nb == VanDerWaalsPotential::Count)
264     {
265         int integerValue = strtol(nb_str, nullptr, 10);
266         if ((integerValue < 1) || (integerValue >= static_cast<int>(VanDerWaalsPotential::Count)))
267         {
268             std::string message =
269                     gmx::formatString("Invalid nonbond function selector '%s' using %s",
270                                       nb_str,
271                                       enumValueToString(VanDerWaalsPotential::LJ));
272             warning_error(wi, message);
273             *nb = VanDerWaalsPotential::LJ;
274         }
275         else
276         {
277             *nb = static_cast<VanDerWaalsPotential>(integerValue);
278         }
279     }
280     *comb = CombinationRule::Count;
281     for (auto i : gmx::EnumerationArray<CombinationRule, bool>::keys())
282     {
283         if (gmx_strcasecmp(comb_str, enumValueToString(i)) == 0)
284         {
285             *comb = i;
286         }
287     }
288     if (*comb == CombinationRule::Count)
289     {
290         int integerValue = strtol(comb_str, nullptr, 10);
291         if ((integerValue < 1) || (integerValue >= static_cast<int>(CombinationRule::Count)))
292         {
293             std::string message =
294                     gmx::formatString("Invalid combination rule selector '%s' using %s",
295                                       comb_str,
296                                       enumValueToString(CombinationRule::Geometric));
297             warning_error(wi, message);
298             *comb = CombinationRule::Geometric;
299         }
300         else
301         {
302             *comb = static_cast<CombinationRule>(integerValue);
303         }
304     }
305 }
306
307 static char** cpp_opts(const char* define, const char* include, warninp* wi)
308 {
309     int         n, len;
310     int         ncppopts = 0;
311     const char* cppadds[2];
312     char**      cppopts   = nullptr;
313     const char* option[2] = { "-D", "-I" };
314     const char* nopt[2]   = { "define", "include" };
315     const char* ptr;
316     const char* rptr;
317     char*       buf;
318     char        warn_buf[STRLEN];
319
320     cppadds[0] = define;
321     cppadds[1] = include;
322     for (n = 0; (n < 2); n++)
323     {
324         if (cppadds[n])
325         {
326             ptr = cppadds[n];
327             while (*ptr != '\0')
328             {
329                 while ((*ptr != '\0') && isspace(*ptr))
330                 {
331                     ptr++;
332                 }
333                 rptr = ptr;
334                 while ((*rptr != '\0') && !isspace(*rptr))
335                 {
336                     rptr++;
337                 }
338                 len = (rptr - ptr);
339                 if (len > 2)
340                 {
341                     snew(buf, (len + 1));
342                     strncpy(buf, ptr, len);
343                     if (strstr(ptr, option[n]) != ptr)
344                     {
345                         set_warning_line(wi, "mdp file", -1);
346                         sprintf(warn_buf, "Malformed %s option %s", nopt[n], buf);
347                         warning(wi, warn_buf);
348                     }
349                     else
350                     {
351                         srenew(cppopts, ++ncppopts);
352                         cppopts[ncppopts - 1] = gmx_strdup(buf);
353                     }
354                     sfree(buf);
355                     ptr = rptr;
356                 }
357             }
358         }
359     }
360     srenew(cppopts, ++ncppopts);
361     cppopts[ncppopts - 1] = nullptr;
362
363     return cppopts;
364 }
365
366
367 static void make_atoms_sys(gmx::ArrayRef<const gmx_molblock_t>      molblock,
368                            gmx::ArrayRef<const MoleculeInformation> molinfo,
369                            t_atoms*                                 atoms)
370 {
371     atoms->nr   = 0;
372     atoms->atom = nullptr;
373
374     for (const gmx_molblock_t& molb : molblock)
375     {
376         const t_atoms& mol_atoms = molinfo[molb.type].atoms;
377
378         srenew(atoms->atom, atoms->nr + molb.nmol * mol_atoms.nr);
379
380         for (int m = 0; m < molb.nmol; m++)
381         {
382             for (int a = 0; a < mol_atoms.nr; a++)
383             {
384                 atoms->atom[atoms->nr++] = mol_atoms.atom[a];
385             }
386         }
387     }
388 }
389
390
391 static char** read_topol(const char*                           infile,
392                          const char*                           outfile,
393                          const char*                           define,
394                          const char*                           include,
395                          t_symtab*                             symtab,
396                          PreprocessingAtomTypes*               atypes,
397                          std::vector<MoleculeInformation>*     molinfo,
398                          std::unique_ptr<MoleculeInformation>* intermolecular_interactions,
399                          gmx::ArrayRef<InteractionsOfType>     interactions,
400                          CombinationRule*                      combination_rule,
401                          double*                               reppow,
402                          t_gromppopts*                         opts,
403                          real*                                 fudgeQQ,
404                          std::vector<gmx_molblock_t>*          molblock,
405                          bool*                                 ffParametrizedWithHBondConstraints,
406                          bool                                  bFEP,
407                          bool                                  bZero,
408                          bool                                  usingFullRangeElectrostatics,
409                          warninp*                              wi,
410                          const gmx::MDLogger&                  logger)
411 {
412     FILE*                out;
413     int                  sl;
414     char *               pline = nullptr, **title = nullptr;
415     char                 line[STRLEN], errbuf[256], comb_str[256], nb_str[256];
416     char                 genpairs[32];
417     char *               dirstr, *dummy2;
418     int                  nrcopies, nscan, ncombs, ncopy;
419     double               fLJ, fQQ, fPOW;
420     MoleculeInformation* mi0 = nullptr;
421     DirStack*            DS;
422     Directive            d, newd;
423     t_nbparam **         nbparam, **pair;
424     real                 fudgeLJ = -1; /* Multiplication factor to generate 1-4 from LJ */
425     bool                 bReadDefaults, bReadMolType, bGenPairs, bWarn_copy_A_B;
426     double               qt = 0, qBt = 0; /* total charge */
427     int                  dcatt = -1, nmol_couple;
428     /* File handling variables */
429     int         status;
430     bool        done;
431     gmx_cpp_t   handle;
432     char*       tmp_line = nullptr;
433     char        warn_buf[STRLEN];
434     const char* floating_point_arithmetic_tip =
435             "Total charge should normally be an integer. See\n"
436             "http://www.gromacs.org/Documentation/Floating_Point_Arithmetic\n"
437             "for discussion on how close it should be to an integer.\n";
438     /* We need to open the output file before opening the input file,
439      * because cpp_open_file can change the current working directory.
440      */
441     if (outfile)
442     {
443         out = gmx_fio_fopen(outfile, "w");
444     }
445     else
446     {
447         out = nullptr;
448     }
449
450     /* open input file */
451     auto cpp_opts_return = cpp_opts(define, include, wi);
452     status               = cpp_open_file(infile, &handle, cpp_opts_return);
453     if (status != 0)
454     {
455         gmx_fatal(FARGS, "%s", cpp_error(&handle, status));
456     }
457
458     /* some local variables */
459     DS_Init(&DS);                   /* directive stack  */
460     d       = Directive::d_invalid; /* first thing should be a directive */
461     nbparam = nullptr;              /* The temporary non-bonded matrix */
462     pair    = nullptr;              /* The temporary pair interaction matrix */
463     std::vector<std::vector<gmx::ExclusionBlock>> exclusionBlocks;
464     VanDerWaalsPotential                          nb_funct = VanDerWaalsPotential::LJ;
465
466     *reppow = 12.0; /* Default value for repulsion power     */
467
468     /* Init the number of CMAP torsion angles  and grid spacing */
469     interactions[F_CMAP].cmakeGridSpacing = 0;
470     interactions[F_CMAP].cmapAngles       = 0;
471
472     bWarn_copy_A_B = bFEP;
473
474     PreprocessingBondAtomType bondAtomType;
475     /* parse the actual file */
476     bReadDefaults = FALSE;
477     bGenPairs     = FALSE;
478     bReadMolType  = FALSE;
479     nmol_couple   = 0;
480
481     do
482     {
483         status = cpp_read_line(&handle, STRLEN, line);
484         done   = (status == eCPP_EOF);
485         if (!done)
486         {
487             if (status != eCPP_OK)
488             {
489                 gmx_fatal(FARGS, "%s", cpp_error(&handle, status));
490             }
491             else if (out)
492             {
493                 fprintf(out, "%s\n", line);
494             }
495
496             set_warning_line(wi, cpp_cur_file(&handle), cpp_cur_linenr(&handle));
497
498             pline = gmx_strdup(line);
499
500             /* Strip trailing '\' from pline, if it exists */
501             sl = strlen(pline);
502             if ((sl > 0) && (pline[sl - 1] == CONTINUE))
503             {
504                 pline[sl - 1] = ' ';
505             }
506
507             /* build one long line from several fragments - necessary for CMAP */
508             while (continuing(line))
509             {
510                 status = cpp_read_line(&handle, STRLEN, line);
511                 set_warning_line(wi, cpp_cur_file(&handle), cpp_cur_linenr(&handle));
512
513                 /* Since we depend on the '\' being present to continue to read, we copy line
514                  * to a tmp string, strip the '\' from that string, and cat it to pline
515                  */
516                 tmp_line = gmx_strdup(line);
517
518                 sl = strlen(tmp_line);
519                 if ((sl > 0) && (tmp_line[sl - 1] == CONTINUE))
520                 {
521                     tmp_line[sl - 1] = ' ';
522                 }
523
524                 done = (status == eCPP_EOF);
525                 if (!done)
526                 {
527                     if (status != eCPP_OK)
528                     {
529                         gmx_fatal(FARGS, "%s", cpp_error(&handle, status));
530                     }
531                     else if (out)
532                     {
533                         fprintf(out, "%s\n", line);
534                     }
535                 }
536
537                 srenew(pline, strlen(pline) + strlen(tmp_line) + 1);
538                 strcat(pline, tmp_line);
539                 sfree(tmp_line);
540             }
541
542             /* skip trailing and leading spaces and comment text */
543             strip_comment(pline);
544             trim(pline);
545
546             /* if there is something left... */
547             if (static_cast<int>(strlen(pline)) > 0)
548             {
549                 if (pline[0] == OPENDIR)
550                 {
551                     /* A directive on this line: copy the directive
552                      * without the brackets into dirstr, then
553                      * skip spaces and tabs on either side of directive
554                      */
555                     dirstr = gmx_strdup((pline + 1));
556                     if ((dummy2 = strchr(dirstr, CLOSEDIR)) != nullptr)
557                     {
558                         (*dummy2) = 0;
559                     }
560                     trim(dirstr);
561
562                     if ((newd = str2dir(dirstr)) == Directive::d_invalid)
563                     {
564                         sprintf(errbuf, "Invalid directive %s", dirstr);
565                         warning_error(wi, errbuf);
566                     }
567                     else
568                     {
569                         /* Directive found */
570                         if (DS_Check_Order(DS, newd))
571                         {
572                             DS_Push(&DS, newd);
573                             d = newd;
574                         }
575                         else
576                         {
577                             /* we should print here which directives should have
578                                been present, and which actually are */
579                             gmx_fatal(FARGS,
580                                       "%s\nInvalid order for directive %s",
581                                       cpp_error(&handle, eCPP_SYNTAX),
582                                       dir2str(newd));
583                             /* d = Directive::d_invalid; */
584                         }
585
586                         if (d == Directive::d_intermolecular_interactions)
587                         {
588                             if (*intermolecular_interactions == nullptr)
589                             {
590                                 /* We (mis)use the moleculetype processing
591                                  * to process the intermolecular interactions
592                                  * by making a "molecule" of the size of the system.
593                                  */
594                                 *intermolecular_interactions = std::make_unique<MoleculeInformation>();
595                                 mi0                          = intermolecular_interactions->get();
596                                 mi0->initMolInfo();
597                                 make_atoms_sys(*molblock, *molinfo, &mi0->atoms);
598                             }
599                         }
600                     }
601                     sfree(dirstr);
602                 }
603                 else if (d != Directive::d_invalid)
604                 {
605                     /* Not a directive, just a plain string
606                      * use a gigantic switch to decode,
607                      * if there is a valid directive!
608                      */
609                     switch (d)
610                     {
611                         case Directive::d_defaults:
612                             if (bReadDefaults)
613                             {
614                                 gmx_fatal(FARGS,
615                                           "%s\nFound a second defaults directive.\n",
616                                           cpp_error(&handle, eCPP_SYNTAX));
617                             }
618                             bReadDefaults = TRUE;
619                             nscan         = sscanf(
620                                     pline, "%s%s%s%lf%lf%lf", nb_str, comb_str, genpairs, &fLJ, &fQQ, &fPOW);
621                             if (nscan < 2)
622                             {
623                                 too_few(wi);
624                             }
625                             else
626                             {
627                                 bGenPairs = FALSE;
628                                 fudgeLJ   = 1.0;
629                                 *fudgeQQ  = 1.0;
630
631                                 get_nbparm(nb_str, comb_str, &nb_funct, combination_rule, wi);
632                                 if (nscan >= 3)
633                                 {
634                                     bGenPairs = (gmx::equalCaseInsensitive(genpairs, "Y", 1));
635                                     if (nb_funct != VanDerWaalsPotential::LJ && bGenPairs)
636                                     {
637                                         gmx_fatal(FARGS,
638                                                   "Generating pair parameters is only supported "
639                                                   "with LJ non-bonded interactions");
640                                     }
641                                 }
642                                 if (nscan >= 4)
643                                 {
644                                     fudgeLJ = fLJ;
645                                 }
646                                 if (nscan >= 5)
647                                 {
648                                     *fudgeQQ = fQQ;
649                                 }
650                                 if (nscan >= 6)
651                                 {
652                                     *reppow = fPOW;
653                                 }
654                             }
655                             nb_funct = static_cast<VanDerWaalsPotential>(ifunc_index(
656                                     Directive::d_nonbond_params, static_cast<int>(nb_funct)));
657
658                             break;
659                         case Directive::d_atomtypes:
660                             push_at(symtab,
661                                     atypes,
662                                     &bondAtomType,
663                                     pline,
664                                     static_cast<int>(nb_funct),
665                                     &nbparam,
666                                     bGenPairs ? &pair : nullptr,
667                                     wi);
668                             break;
669
670                         case Directive::d_bondtypes: // Intended to fall through
671                         case Directive::d_constrainttypes:
672                             push_bt(d, interactions, 2, nullptr, &bondAtomType, pline, wi);
673                             break;
674                         case Directive::d_pairtypes:
675                             if (bGenPairs)
676                             {
677                                 push_nbt(d, pair, atypes, pline, F_LJ14, wi);
678                             }
679                             else
680                             {
681                                 push_bt(d, interactions, 2, atypes, nullptr, pline, wi);
682                             }
683                             break;
684                         case Directive::d_angletypes:
685                             push_bt(d, interactions, 3, nullptr, &bondAtomType, pline, wi);
686                             break;
687                         case Directive::d_dihedraltypes:
688                             /* Special routine that can read both 2 and 4 atom dihedral definitions. */
689                             push_dihedraltype(d, interactions, &bondAtomType, pline, wi);
690                             break;
691
692                         case Directive::d_nonbond_params:
693                             push_nbt(d, nbparam, atypes, pline, static_cast<int>(nb_funct), wi);
694                             break;
695
696                         case Directive::d_implicit_genborn_params: // NOLINT bugprone-branch-clone
697                             // Skip this line, so old topologies with
698                             // GB parameters can be read.
699                             break;
700
701                         case Directive::d_implicit_surface_params:
702                             // Skip this line, so that any topologies
703                             // with surface parameters can be read
704                             // (even though these were never formally
705                             // supported).
706                             break;
707
708                         case Directive::d_cmaptypes:
709                             push_cmaptype(d, interactions, 5, atypes, &bondAtomType, pline, wi);
710                             break;
711
712                         case Directive::d_moleculetype:
713                         {
714                             if (!bReadMolType)
715                             {
716                                 int ntype;
717                                 if (opts->couple_moltype != nullptr
718                                     && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam0 == ecouplamQ
719                                         || opts->couple_lam1 == ecouplamNONE
720                                         || opts->couple_lam1 == ecouplamQ))
721                                 {
722                                     dcatt = add_atomtype_decoupled(
723                                             symtab, atypes, &nbparam, bGenPairs ? &pair : nullptr);
724                                 }
725                                 ntype  = atypes->size();
726                                 ncombs = (ntype * (ntype + 1)) / 2;
727                                 generate_nbparams(*combination_rule,
728                                                   static_cast<int>(nb_funct),
729                                                   &(interactions[static_cast<int>(nb_funct)]),
730                                                   atypes,
731                                                   wi);
732                                 ncopy = copy_nbparams(nbparam,
733                                                       static_cast<int>(nb_funct),
734                                                       &(interactions[static_cast<int>(nb_funct)]),
735                                                       ntype);
736                                 GMX_LOG(logger.info)
737                                         .asParagraph()
738                                         .appendTextFormatted(
739                                                 "Generated %d of the %d non-bonded parameter "
740                                                 "combinations",
741                                                 ncombs - ncopy,
742                                                 ncombs);
743                                 free_nbparam(nbparam, ntype);
744                                 if (bGenPairs)
745                                 {
746                                     gen_pairs((interactions[static_cast<int>(nb_funct)]),
747                                               &(interactions[F_LJ14]),
748                                               fudgeLJ,
749                                               *combination_rule);
750                                     ncopy = copy_nbparams(
751                                             pair, static_cast<int>(nb_funct), &(interactions[F_LJ14]), ntype);
752                                     GMX_LOG(logger.info)
753                                             .asParagraph()
754                                             .appendTextFormatted(
755                                                     "Generated %d of the %d 1-4 parameter "
756                                                     "combinations",
757                                                     ncombs - ncopy,
758                                                     ncombs);
759                                     free_nbparam(pair, ntype);
760                                 }
761                                 /* Copy GBSA parameters to atomtype array? */
762
763                                 bReadMolType = TRUE;
764                             }
765
766                             push_molt(symtab, molinfo, pline, wi);
767                             exclusionBlocks.emplace_back();
768                             mi0                    = &molinfo->back();
769                             mi0->atoms.haveMass    = TRUE;
770                             mi0->atoms.haveCharge  = TRUE;
771                             mi0->atoms.haveType    = TRUE;
772                             mi0->atoms.haveBState  = TRUE;
773                             mi0->atoms.havePdbInfo = FALSE;
774                             break;
775                         }
776                         case Directive::d_atoms:
777                             push_atom(symtab, &(mi0->atoms), atypes, pline, wi);
778                             break;
779
780                         case Directive::d_pairs:
781                             GMX_RELEASE_ASSERT(
782                                     mi0,
783                                     "Need to have a valid MoleculeInformation object to work on");
784                             push_bond(d,
785                                       interactions,
786                                       mi0->interactions,
787                                       &(mi0->atoms),
788                                       atypes,
789                                       pline,
790                                       FALSE,
791                                       bGenPairs,
792                                       *fudgeQQ,
793                                       bZero,
794                                       &bWarn_copy_A_B,
795                                       wi);
796                             break;
797                         case Directive::d_pairs_nb:
798                             GMX_RELEASE_ASSERT(
799                                     mi0,
800                                     "Need to have a valid MoleculeInformation object to work on");
801                             push_bond(d,
802                                       interactions,
803                                       mi0->interactions,
804                                       &(mi0->atoms),
805                                       atypes,
806                                       pline,
807                                       FALSE,
808                                       FALSE,
809                                       1.0,
810                                       bZero,
811                                       &bWarn_copy_A_B,
812                                       wi);
813                             break;
814
815                         case Directive::d_vsites1:
816                         case Directive::d_vsites2:
817                         case Directive::d_vsites3:
818                         case Directive::d_vsites4:
819                         case Directive::d_bonds:
820                         case Directive::d_angles:
821                         case Directive::d_constraints:
822                         case Directive::d_settles:
823                         case Directive::d_position_restraints:
824                         case Directive::d_angle_restraints:
825                         case Directive::d_angle_restraints_z:
826                         case Directive::d_distance_restraints:
827                         case Directive::d_orientation_restraints:
828                         case Directive::d_dihedral_restraints:
829                         case Directive::d_dihedrals:
830                         case Directive::d_polarization:
831                         case Directive::d_water_polarization:
832                         case Directive::d_thole_polarization:
833                             GMX_RELEASE_ASSERT(
834                                     mi0,
835                                     "Need to have a valid MoleculeInformation object to work on");
836                             push_bond(d,
837                                       interactions,
838                                       mi0->interactions,
839                                       &(mi0->atoms),
840                                       atypes,
841                                       pline,
842                                       TRUE,
843                                       bGenPairs,
844                                       *fudgeQQ,
845                                       bZero,
846                                       &bWarn_copy_A_B,
847                                       wi);
848                             break;
849                         case Directive::d_cmap:
850                             GMX_RELEASE_ASSERT(
851                                     mi0,
852                                     "Need to have a valid MoleculeInformation object to work on");
853                             push_cmap(d, interactions, mi0->interactions, &(mi0->atoms), atypes, pline, wi);
854                             break;
855
856                         case Directive::d_vsitesn:
857                             GMX_RELEASE_ASSERT(
858                                     mi0,
859                                     "Need to have a valid MoleculeInformation object to work on");
860                             push_vsitesn(d, mi0->interactions, &(mi0->atoms), pline, wi);
861                             break;
862                         case Directive::d_exclusions:
863                             GMX_ASSERT(!exclusionBlocks.empty(),
864                                        "exclusionBlocks must always be allocated so exclusions can "
865                                        "be processed");
866                             if (exclusionBlocks.back().empty())
867                             {
868                                 GMX_RELEASE_ASSERT(mi0,
869                                                    "Need to have a valid MoleculeInformation "
870                                                    "object to work on");
871                                 exclusionBlocks.back().resize(mi0->atoms.nr);
872                             }
873                             push_excl(pline, exclusionBlocks.back(), wi);
874                             break;
875                         case Directive::d_system:
876                             trim(pline);
877                             title = put_symtab(symtab, pline);
878                             break;
879                         case Directive::d_molecules:
880                         {
881                             int  whichmol;
882                             bool bCouple;
883
884                             push_mol(*molinfo, pline, &whichmol, &nrcopies, wi);
885                             mi0 = &((*molinfo)[whichmol]);
886                             molblock->resize(molblock->size() + 1);
887                             molblock->back().type = whichmol;
888                             molblock->back().nmol = nrcopies;
889
890                             bCouple = (opts->couple_moltype != nullptr
891                                        && (gmx_strcasecmp("system", opts->couple_moltype) == 0
892                                            || strcmp(*(mi0->name), opts->couple_moltype) == 0));
893                             if (bCouple)
894                             {
895                                 nmol_couple += nrcopies;
896                             }
897
898                             if (mi0->atoms.nr == 0)
899                             {
900                                 gmx_fatal(FARGS, "Molecule type '%s' contains no atoms", *mi0->name);
901                             }
902                             GMX_LOG(logger.info)
903                                     .asParagraph()
904                                     .appendTextFormatted(
905                                             "Excluding %d bonded neighbours molecule type '%s'",
906                                             mi0->nrexcl,
907                                             *mi0->name);
908                             sum_q(&mi0->atoms, nrcopies, &qt, &qBt);
909                             if (!mi0->bProcessed)
910                             {
911                                 generate_excl(mi0->nrexcl, mi0->atoms.nr, mi0->interactions, &(mi0->excls));
912                                 gmx::mergeExclusions(&(mi0->excls), exclusionBlocks[whichmol]);
913                                 make_shake(mi0->interactions, &mi0->atoms, opts->nshake, logger);
914
915                                 if (bCouple)
916                                 {
917                                     convert_moltype_couple(mi0,
918                                                            dcatt,
919                                                            *fudgeQQ,
920                                                            opts->couple_lam0,
921                                                            opts->couple_lam1,
922                                                            opts->bCoupleIntra,
923                                                            static_cast<int>(nb_funct),
924                                                            &(interactions[static_cast<int>(nb_funct)]),
925                                                            wi);
926                                 }
927                                 stupid_fill_block(&mi0->mols, mi0->atoms.nr, TRUE);
928                                 mi0->bProcessed = TRUE;
929                             }
930                             break;
931                         }
932                         default:
933                             GMX_LOG(logger.warning)
934                                     .asParagraph()
935                                     .appendTextFormatted("case: %d", static_cast<int>(d));
936                             gmx_incons("unknown directive");
937                     }
938                 }
939             }
940             sfree(pline);
941             pline = nullptr;
942         }
943     } while (!done);
944
945     // Check that all strings defined with -D were used when processing topology
946     std::string unusedDefineWarning = checkAndWarnForUnusedDefines(*handle);
947     if (!unusedDefineWarning.empty())
948     {
949         warning(wi, unusedDefineWarning);
950     }
951
952     sfree(cpp_opts_return);
953
954     if (out)
955     {
956         gmx_fio_fclose(out);
957     }
958
959     /* List of GROMACS define names for force fields that have been
960      * parametrized using constraints involving hydrogens only.
961      *
962      * We should avoid hardcoded names, but this is hopefully only
963      * needed temparorily for discouraging use of constraints=all-bonds.
964      */
965     const std::array<std::string, 3> ffDefines = { "_FF_AMBER", "_FF_CHARMM", "_FF_OPLSAA" };
966     *ffParametrizedWithHBondConstraints        = false;
967     for (const std::string& ffDefine : ffDefines)
968     {
969         if (cpp_find_define(&handle, ffDefine))
970         {
971             *ffParametrizedWithHBondConstraints = true;
972         }
973     }
974
975     if (cpp_find_define(&handle, "_FF_GROMOS96") != nullptr)
976     {
977         warning(wi,
978                 "The GROMOS force fields have been parametrized with a physically incorrect "
979                 "multiple-time-stepping scheme for a twin-range cut-off. When used with "
980                 "a single-range cut-off (or a correct Trotter multiple-time-stepping scheme), "
981                 "physical properties, such as the density, might differ from the intended values. "
982                 "Since there are researchers actively working on validating GROMOS with modern "
983                 "integrators we have not yet removed the GROMOS force fields, but you should be "
984                 "aware of these issues and check if molecules in your system are affected before "
985                 "proceeding. "
986                 "Further information is available at https://redmine.gromacs.org/issues/2884 , "
987                 "and a longer explanation of our decision to remove physically incorrect "
988                 "algorithms "
989                 "can be found at https://doi.org/10.26434/chemrxiv.11474583.v1 .");
990     }
991     // TODO: Update URL for Issue #2884 in conjunction with updating grompp.warn in regressiontests.
992
993     cpp_done(handle);
994
995     if (opts->couple_moltype)
996     {
997         if (nmol_couple == 0)
998         {
999             gmx_fatal(FARGS, "Did not find any molecules of type '%s' for coupling", opts->couple_moltype);
1000         }
1001         GMX_LOG(logger.info)
1002                 .asParagraph()
1003                 .appendTextFormatted(
1004                         "Coupling %d copies of molecule type '%s'", nmol_couple, opts->couple_moltype);
1005     }
1006
1007     /* this is not very clean, but fixes core dump on empty system name */
1008     if (!title)
1009     {
1010         title = put_symtab(symtab, "");
1011     }
1012
1013     if (fabs(qt) > 1e-4)
1014     {
1015         sprintf(warn_buf, "System has non-zero total charge: %.6f\n%s\n", qt, floating_point_arithmetic_tip);
1016         warning_note(wi, warn_buf);
1017     }
1018     if (fabs(qBt) > 1e-4 && !gmx_within_tol(qBt, qt, 1e-6))
1019     {
1020         sprintf(warn_buf, "State B has non-zero total charge: %.6f\n%s\n", qBt, floating_point_arithmetic_tip);
1021         warning_note(wi, warn_buf);
1022     }
1023     if (usingFullRangeElectrostatics && (fabs(qt) > 1e-4 || fabs(qBt) > 1e-4))
1024     {
1025         warning(wi,
1026                 "You are using Ewald electrostatics in a system with net charge. This can lead to "
1027                 "severe artifacts, such as ions moving into regions with low dielectric, due to "
1028                 "the uniform background charge. We suggest to neutralize your system with counter "
1029                 "ions, possibly in combination with a physiological salt concentration.");
1030         please_cite(stdout, "Hub2014a");
1031     }
1032
1033     DS_Done(&DS);
1034
1035     if (*intermolecular_interactions != nullptr)
1036     {
1037         sfree(intermolecular_interactions->get()->atoms.atom);
1038     }
1039
1040     return title;
1041 }
1042
1043 char** do_top(bool                                  bVerbose,
1044               const char*                           topfile,
1045               const char*                           topppfile,
1046               t_gromppopts*                         opts,
1047               bool                                  bZero,
1048               t_symtab*                             symtab,
1049               gmx::ArrayRef<InteractionsOfType>     interactions,
1050               CombinationRule*                      combination_rule,
1051               double*                               repulsion_power,
1052               real*                                 fudgeQQ,
1053               PreprocessingAtomTypes*               atypes,
1054               std::vector<MoleculeInformation>*     molinfo,
1055               std::unique_ptr<MoleculeInformation>* intermolecular_interactions,
1056               const t_inputrec*                     ir,
1057               std::vector<gmx_molblock_t>*          molblock,
1058               bool*                                 ffParametrizedWithHBondConstraints,
1059               warninp*                              wi,
1060               const gmx::MDLogger&                  logger)
1061 {
1062     /* Tmpfile might contain a long path */
1063     const char* tmpfile;
1064     char**      title;
1065
1066     if (topppfile)
1067     {
1068         tmpfile = topppfile;
1069     }
1070     else
1071     {
1072         tmpfile = nullptr;
1073     }
1074
1075     if (bVerbose)
1076     {
1077         GMX_LOG(logger.info).asParagraph().appendTextFormatted("processing topology...");
1078     }
1079     title = read_topol(topfile,
1080                        tmpfile,
1081                        opts->define,
1082                        opts->include,
1083                        symtab,
1084                        atypes,
1085                        molinfo,
1086                        intermolecular_interactions,
1087                        interactions,
1088                        combination_rule,
1089                        repulsion_power,
1090                        opts,
1091                        fudgeQQ,
1092                        molblock,
1093                        ffParametrizedWithHBondConstraints,
1094                        ir->efep != FreeEnergyPerturbationType::No,
1095                        bZero,
1096                        EEL_FULL(ir->coulombtype),
1097                        wi,
1098                        logger);
1099
1100     if ((*combination_rule != CombinationRule::Geometric) && (ir->vdwtype == VanDerWaalsType::User))
1101     {
1102         warning(wi,
1103                 "Using sigma/epsilon based combination rules with"
1104                 " user supplied potential function may produce unwanted"
1105                 " results");
1106     }
1107
1108     return title;
1109 }
1110
1111 /*! \brief
1112  * Exclude molecular interactions for QM atoms handled by MiMic.
1113  *
1114  * Update the exclusion lists to include all QM atoms of this molecule,
1115  * replace bonds between QM atoms with CONNBOND and
1116  * set charges of QM atoms to 0.
1117  *
1118  * \param[in,out] molt molecule type with QM atoms
1119  * \param[in] grpnr group informatio
1120  * \param[in,out] ir input record
1121  * \param[in] logger Handle to logging interface.
1122  */
1123 static void generate_qmexcl_moltype(gmx_moltype_t*       molt,
1124                                     const unsigned char* grpnr,
1125                                     t_inputrec*          ir,
1126                                     const gmx::MDLogger& logger)
1127 {
1128     /* This routine expects molt->ilist to be of size F_NRE and ordered. */
1129
1130     /* generates the exclusions between the individual QM atoms, as
1131      * these interactions should be handled by the QM subroutines and
1132      * not by the gromacs routines
1133      */
1134     int   qm_max = 0, qm_nr = 0, link_nr = 0;
1135     int * qm_arr = nullptr, *link_arr = nullptr;
1136     bool* bQMMM;
1137
1138     /* First we search and select the QM atoms in an qm_arr array that
1139      * we use to create the exclusions.
1140      *
1141      * we take the possibility into account that a user has defined more
1142      * than one QM group:
1143      *
1144      * for that we also need to do this an ugly work-about just in case
1145      * the QM group contains the entire system...
1146      */
1147
1148     /* we first search for all the QM atoms and put them in an array
1149      */
1150     for (int j = 0; j < ir->opts.ngQM; j++)
1151     {
1152         for (int i = 0; i < molt->atoms.nr; i++)
1153         {
1154             if (qm_nr >= qm_max)
1155             {
1156                 qm_max += 100;
1157                 srenew(qm_arr, qm_max);
1158             }
1159             if ((grpnr ? grpnr[i] : 0) == j)
1160             {
1161                 qm_arr[qm_nr++]        = i;
1162                 molt->atoms.atom[i].q  = 0.0;
1163                 molt->atoms.atom[i].qB = 0.0;
1164             }
1165         }
1166     }
1167     /* bQMMM[..] is an array containin TRUE/FALSE for atoms that are
1168      * QM/not QM. We first set all elements to false. Afterwards we use
1169      * the qm_arr to change the elements corresponding to the QM atoms
1170      * to TRUE.
1171      */
1172     snew(bQMMM, molt->atoms.nr);
1173     for (int i = 0; i < molt->atoms.nr; i++)
1174     {
1175         bQMMM[i] = FALSE;
1176     }
1177     for (int i = 0; i < qm_nr; i++)
1178     {
1179         bQMMM[qm_arr[i]] = TRUE;
1180     }
1181
1182     /* We remove all bonded interactions (i.e. bonds,
1183      * angles, dihedrals, 1-4's), involving the QM atoms. The way they
1184      * are removed is as follows: if the interaction invloves 2 atoms,
1185      * it is removed if both atoms are QMatoms. If it involves 3 atoms,
1186      * it is removed if at least two of the atoms are QM atoms, if the
1187      * interaction involves 4 atoms, it is removed if there are at least
1188      * 2 QM atoms.  Since this routine is called once before any forces
1189      * are computed, the top->idef.il[N].iatom[] array (see idef.h) can
1190      * be rewritten at this poitn without any problem. 25-9-2002 */
1191
1192     /* first check whether we already have CONNBONDS.
1193      * Note that if we don't, we don't add a param entry and set ftype=0,
1194      * which is ok, since CONNBONDS does not use parameters.
1195      */
1196     int ftype_connbond = 0;
1197     int ind_connbond   = 0;
1198     if (!molt->ilist[F_CONNBONDS].empty())
1199     {
1200         GMX_LOG(logger.info)
1201                 .asParagraph()
1202                 .appendTextFormatted("nr. of CONNBONDS present already: %d",
1203                                      molt->ilist[F_CONNBONDS].size() / 3);
1204         ftype_connbond = molt->ilist[F_CONNBONDS].iatoms[0];
1205         ind_connbond   = molt->ilist[F_CONNBONDS].size();
1206     }
1207     /* now we delete all bonded interactions, except the ones describing
1208      * a chemical bond. These are converted to CONNBONDS
1209      */
1210     for (int ftype = 0; ftype < F_NRE; ftype++)
1211     {
1212         if (!(interaction_function[ftype].flags & IF_BOND) || ftype == F_CONNBONDS)
1213         {
1214             continue;
1215         }
1216         int nratoms = interaction_function[ftype].nratoms;
1217         int j       = 0;
1218         while (j < molt->ilist[ftype].size())
1219         {
1220             bool bexcl;
1221
1222             if (nratoms == 2)
1223             {
1224                 /* Remove an interaction between two atoms when both are
1225                  * in the QM region. Note that we don't have to worry about
1226                  * link atoms here, as they won't have 2-atom interactions.
1227                  */
1228                 int a1 = molt->ilist[ftype].iatoms[1 + j + 0];
1229                 int a2 = molt->ilist[ftype].iatoms[1 + j + 1];
1230                 bexcl  = (bQMMM[a1] && bQMMM[a2]);
1231                 /* A chemical bond between two QM atoms will be copied to
1232                  * the F_CONNBONDS list, for reasons mentioned above.
1233                  */
1234                 if (bexcl && IS_CHEMBOND(ftype))
1235                 {
1236                     InteractionList& ilist = molt->ilist[F_CONNBONDS];
1237                     ilist.iatoms.resize(ind_connbond + 3);
1238                     ilist.iatoms[ind_connbond++] = ftype_connbond;
1239                     ilist.iatoms[ind_connbond++] = a1;
1240                     ilist.iatoms[ind_connbond++] = a2;
1241                 }
1242             }
1243             else
1244             {
1245                 /* MM interactions have to be excluded if they are included
1246                  * in the QM already. Because we use a link atom (H atom)
1247                  * when the QM/MM boundary runs through a chemical bond, this
1248                  * means that as long as one atom is MM, we still exclude,
1249                  * as the interaction is included in the QM via:
1250                  * QMatom1-QMatom2-QMatom-3-Linkatom.
1251                  */
1252                 int numQmAtoms = 0;
1253                 for (int jj = j + 1; jj < j + 1 + nratoms; jj++)
1254                 {
1255                     if (bQMMM[molt->ilist[ftype].iatoms[jj]])
1256                     {
1257                         numQmAtoms++;
1258                     }
1259                 }
1260
1261                 /* MiMiC treats link atoms as quantum atoms - therefore
1262                  * we do not need do additional exclusions here */
1263                 bexcl = numQmAtoms == nratoms;
1264
1265                 if (bexcl && ftype == F_SETTLE)
1266                 {
1267                     gmx_fatal(FARGS,
1268                               "Can not apply QM to molecules with SETTLE, replace the moleculetype "
1269                               "using QM and SETTLE by one without SETTLE");
1270                 }
1271             }
1272             if (bexcl)
1273             {
1274                 /* since the interaction involves QM atoms, these should be
1275                  * removed from the MM ilist
1276                  */
1277                 InteractionList& ilist = molt->ilist[ftype];
1278                 for (int k = j; k < ilist.size() - (nratoms + 1); k++)
1279                 {
1280                     ilist.iatoms[k] = ilist.iatoms[k + (nratoms + 1)];
1281                 }
1282                 ilist.iatoms.resize(ilist.size() - (nratoms + 1));
1283             }
1284             else
1285             {
1286                 j += nratoms + 1; /* the +1 is for the functype */
1287             }
1288         }
1289     }
1290     /* Now, we search for atoms bonded to a QM atom because we also want
1291      * to exclude their nonbonded interactions with the QM atoms. The
1292      * reason for this is that this interaction is accounted for in the
1293      * linkatoms interaction with the QMatoms and would be counted
1294      * twice.  */
1295
1296     /* creating the exclusion block for the QM atoms. Each QM atom has
1297      * as excluded elements all the other QMatoms (and itself).
1298      */
1299     t_blocka qmexcl;
1300     qmexcl.nr  = molt->atoms.nr;
1301     qmexcl.nra = qm_nr * (qm_nr + link_nr) + link_nr * qm_nr;
1302     snew(qmexcl.index, qmexcl.nr + 1);
1303     snew(qmexcl.a, qmexcl.nra);
1304     int j = 0;
1305     for (int i = 0; i < qmexcl.nr; i++)
1306     {
1307         qmexcl.index[i] = j;
1308         if (bQMMM[i])
1309         {
1310             for (int k = 0; k < qm_nr; k++)
1311             {
1312                 qmexcl.a[k + j] = qm_arr[k];
1313             }
1314             for (int k = 0; k < link_nr; k++)
1315             {
1316                 qmexcl.a[qm_nr + k + j] = link_arr[k];
1317             }
1318             j += (qm_nr + link_nr);
1319         }
1320     }
1321     qmexcl.index[qmexcl.nr] = j;
1322
1323     /* and merging with the exclusions already present in sys.
1324      */
1325
1326     std::vector<gmx::ExclusionBlock> qmexcl2(molt->atoms.nr);
1327     gmx::blockaToExclusionBlocks(&qmexcl, qmexcl2);
1328     gmx::mergeExclusions(&(molt->excls), qmexcl2);
1329
1330     /* Finally, we also need to get rid of the pair interactions of the
1331      * classical atom bonded to the boundary QM atoms with the QMatoms,
1332      * as this interaction is already accounted for by the QM, so also
1333      * here we run the risk of double counting! We proceed in a similar
1334      * way as we did above for the other bonded interactions: */
1335     for (int i = F_LJ14; i < F_COUL14; i++)
1336     {
1337         int nratoms = interaction_function[i].nratoms;
1338         int j       = 0;
1339         while (j < molt->ilist[i].size())
1340         {
1341             int  a1    = molt->ilist[i].iatoms[j + 1];
1342             int  a2    = molt->ilist[i].iatoms[j + 2];
1343             bool bexcl = (bQMMM[a1] && bQMMM[a2]);
1344             if (bexcl)
1345             {
1346                 /* since the interaction involves QM atoms, these should be
1347                  * removed from the MM ilist
1348                  */
1349                 InteractionList& ilist = molt->ilist[i];
1350                 for (int k = j; k < ilist.size() - (nratoms + 1); k++)
1351                 {
1352                     ilist.iatoms[k] = ilist.iatoms[k + (nratoms + 1)];
1353                 }
1354                 ilist.iatoms.resize(ilist.size() - (nratoms + 1));
1355             }
1356             else
1357             {
1358                 j += nratoms + 1; /* the +1 is for the functype */
1359             }
1360         }
1361     }
1362
1363     free(qm_arr);
1364     free(bQMMM);
1365     free(link_arr);
1366 } /* generate_qmexcl */
1367
1368 void generate_qmexcl(gmx_mtop_t* sys, t_inputrec* ir, const gmx::MDLogger& logger)
1369 {
1370     /* This routine expects molt->molt[m].ilist to be of size F_NRE and ordered.
1371      */
1372
1373     unsigned char*  grpnr;
1374     int             mol, nat_mol, nr_mol_with_qm_atoms = 0;
1375     gmx_molblock_t* molb;
1376     bool            bQMMM;
1377     int             index_offset = 0;
1378     int             qm_nr        = 0;
1379
1380     grpnr = sys->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data();
1381
1382     for (size_t mb = 0; mb < sys->molblock.size(); mb++)
1383     {
1384         molb    = &sys->molblock[mb];
1385         nat_mol = sys->moltype[molb->type].atoms.nr;
1386         for (mol = 0; mol < molb->nmol; mol++)
1387         {
1388             bQMMM = FALSE;
1389             for (int i = 0; i < nat_mol; i++)
1390             {
1391                 if ((grpnr ? grpnr[i] : 0) < (ir->opts.ngQM))
1392                 {
1393                     bQMMM = TRUE;
1394                     qm_nr++;
1395                 }
1396             }
1397
1398             if (bQMMM)
1399             {
1400                 nr_mol_with_qm_atoms++;
1401                 if (molb->nmol > 1)
1402                 {
1403                     /* We need to split this molblock */
1404                     if (mol > 0)
1405                     {
1406                         /* Split the molblock at this molecule */
1407                         auto pos = sys->molblock.begin() + mb + 1;
1408                         sys->molblock.insert(pos, sys->molblock[mb]);
1409                         sys->molblock[mb].nmol = mol;
1410                         sys->molblock[mb + 1].nmol -= mol;
1411                         mb++;
1412                         molb = &sys->molblock[mb];
1413                     }
1414                     if (molb->nmol > 1)
1415                     {
1416                         /* Split the molblock after this molecule */
1417                         auto pos = sys->molblock.begin() + mb + 1;
1418                         sys->molblock.insert(pos, sys->molblock[mb]);
1419                         molb                   = &sys->molblock[mb];
1420                         sys->molblock[mb].nmol = 1;
1421                         sys->molblock[mb + 1].nmol -= 1;
1422                     }
1423
1424                     /* Create a copy of a moltype for a molecule
1425                      * containing QM atoms and append it in the end of the list
1426                      */
1427                     std::vector<gmx_moltype_t> temp(sys->moltype.size());
1428                     for (size_t i = 0; i < sys->moltype.size(); ++i)
1429                     {
1430                         copy_moltype(&sys->moltype[i], &temp[i]);
1431                     }
1432                     sys->moltype.resize(sys->moltype.size() + 1);
1433                     for (size_t i = 0; i < temp.size(); ++i)
1434                     {
1435                         copy_moltype(&temp[i], &sys->moltype[i]);
1436                     }
1437                     copy_moltype(&sys->moltype[molb->type], &sys->moltype.back());
1438                     /* Copy the exclusions to a new array, since this is the only
1439                      * thing that needs to be modified for QMMM.
1440                      */
1441                     sys->moltype.back().excls = sys->moltype[molb->type].excls;
1442                     /* Set the molecule type for the QMMM molblock */
1443                     molb->type = sys->moltype.size() - 1;
1444                 }
1445                 generate_qmexcl_moltype(&sys->moltype[molb->type], grpnr, ir, logger);
1446             }
1447             if (grpnr)
1448             {
1449                 grpnr += nat_mol;
1450             }
1451             index_offset += nat_mol;
1452         }
1453     }
1454 }